Distributed States Temporal Logic
Carlo Montangero \quad Laura Semini
We introduce a temporal logic to reason on global applications in an asynchronous setting. First, we define the Distributed States Logic (DSL), a modal logic for localities that embeds the local theories of each component into a theory of the distributed states of the system. We provide the logic with a sound and complete axiomatization. The contribution is that it is possible to reason about properties that involve several components, even in the absence of a global clock. Then, we define the Distributed States Temporal Logic (DSTL) by introducing temporal operators \`a la Unity. We support our proposal by working out a pair of examples: a simple secure communication system, and an algorithm for distributed leader election. The motivation for this work is that the existing logics for distributed systems do not have the right expressive power to reason on the systems behaviour, when the communication is based on asynchronous message passing. On the other side, asynchronous communication is the most used abstraction when modelling global applications.
dstlMoSe.tex
\documentclass[11pt]{llncs}

\usepackage{llncsdoc}
\usepackage{amsfonts}



\setlength{\textheight}{23.3cm}
\setlength{\textwidth}{15.4cm}
\addtolength{\oddsidemargin}{-1.7cm}
\addtolength{\evensidemargin}{-1.7cm}
\addtolength{\topmargin}{-1cm}
 

%\usepackage{newproof}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%versione modificata di proof.tex : cancellate le righe in cui compare
%\mscount. 


\def\introrule{{\cal I}}\def\elimrule{{\cal E}}%%
\def\andintro{\using{\land}\introrule\justifies}%%
\def\impelim{\using{\Rightarrow}\elimrule\justifies}%%
\def\allintro{\using{\forall}\introrule\justifies}%%
\def\allelim{\using{\forall}\elimrule\justifies}%%
\def\falseelim{\using{\bot}\elimrule\justifies}%%
\def\existsintro{\using{\exists}\introrule\justifies}%%

%% #1 is meant to be 1 or 2 for the first or second formula
\def\andelim#1{\using{\land}#1\elimrule\justifies}%%
\def\orintro#1{\using{\lor}#1\introrule\justifies}%%

%% #1 is meant to be a label corresponding to the discharged hypothesis/es
\def\impintro#1{\using{\Rightarrow}\introrule_{#1}\justifies}%%
\def\orelim#1{\using{\lor}\elimrule_{#1}\justifies}%%
\def\existselim#1{\using{\exists}\elimrule_{#1}\justifies}

%%==========================================================================

\newdimen\proofrulebreadth \proofrulebreadth=.05em
\newdimen\proofdotseparation \proofdotseparation=1.25ex
\newdimen\proofrulebaseline \proofrulebaseline=2ex
\newcount\proofdotnumber \proofdotnumber=3
\let\then\relax
\def\hfi{\hskip0pt plus.0001fil}
\mathchardef\squigto="3A3B
%
% flag where we are
\newif\ifinsideprooftree\insideprooftreefalse
\newif\ifonleftofproofrule\onleftofproofrulefalse
\newif\ifproofdots\proofdotsfalse
\newif\ifdoubleproof\doubleprooffalse
\let\wereinproofbit\relax
%
% dimensions and boxes of bits
\newdimen\shortenproofleft
\newdimen\shortenproofright
\newdimen\proofbelowshift
\newbox\proofabove
\newbox\proofbelow
\newbox\proofrulename
%
% miscellaneous commands for setting values
\def\shiftproofbelow{\let\next\relax\afterassignment\setshiftproofbelow\dimen0
}

\def\shiftproofbelowneg{\def\next{\multiply\dimen0 by-1 }%
\afterassignment\setshiftproofbelow\dimen0 }
\def\setshiftproofbelow{\next\proofbelowshift=\dimen0 }
\def\setproofrulebreadth{\proofrulebreadth}

%=============================================================================
\def\prooftree{% NESTED ZERO (\ifonleftofproofrule)
%
% first find out whether we're at the left-hand end of a proof rule
\ifnum  \lastpenalty=1
\then   \unpenalty
\else   \onleftofproofrulefalse
\fi
%
% some space on left (except if we're on left, and no infinity for outermost)
\ifonleftofproofrule
\else   \ifinsideprooftree
        \then   \hskip.5em plus1fil
        \fi
\fi
%
% begin our proof tree environment
\bgroup% NESTED ONE (\proofbelow, \proofrulename, \proofabove,
%               \shortenproofleft, \shortenproofright, \proofrulebreadth)
\setbox\proofbelow=\hbox{}\setbox\proofrulename=\hbox{}%
\let\justifies\proofover\let\leadsto\proofoverdots\let\Justifies\proofoverdbl
\let\using\proofusing\let\[\prooftree
\ifinsideprooftree\let\]\endprooftree\fi
\proofdotsfalse\doubleprooffalse
\let\thickness\setproofrulebreadth
\let\shiftright\shiftproofbelow \let\shift\shiftproofbelow
\let\shiftleft\shiftproofbelowneg
\let\ifwasinsideprooftree\ifinsideprooftree
\insideprooftreetrue
%
% now begin to set the top of the rule (definitions local to it)
\setbox\proofabove=\hbox\bgroup$\displaystyle % NESTED TWO
\let\wereinproofbit\prooftree
%
% these local variables will be copied out:
\shortenproofleft=0pt \shortenproofright=0pt \proofbelowshift=0pt
%
% flags to enable inner proof tree to detect if on left:
\onleftofproofruletrue\penalty1
}

%=============================================================================
% end whatever box and copy crucial values out of it
\def\eproofbit{% NESTED TWO
%
% various hacks applicable to hypothesis list 
\ifx    \wereinproofbit\prooftree
\then   \ifcase \lastpenalty
        \then   \shortenproofright=0pt  % 0: some other object, no indentation
        \or     \unpenalty\hfil         % 1: empty hypotheses, just glue
        \or     \unpenalty\unskip       % 2: just had a tree, remove glue
        \else   \shortenproofright=0pt  % eh?
        \fi
\fi
%
% pass out crucial values from scope
\global\dimen0=\shortenproofleft
\global\dimen1=\shortenproofright
\global\dimen2=\proofrulebreadth
\global\dimen3=\proofbelowshift
\global\dimen4=\proofdotseparation
%\global\mscount=\proofdotnumber
%
% end the box
$\egroup  % NESTED ONE
%
% restore the values
\shortenproofleft=\dimen0
\shortenproofright=\dimen1
\proofrulebreadth=\dimen2
\proofbelowshift=\dimen3
\proofdotseparation=\dimen4
%\proofdotnumber=\mscount
}

%=============================================================================
\def\proofover{% NESTED TWO
\eproofbit % NESTED ONE
\setbox\proofbelow=\hbox\bgroup % NESTED TWO
\let\wereinproofbit\proofover
$\displaystyle
}%
%
%=============================================================================
\def\proofoverdbl{% NESTED TWO
\eproofbit % NESTED ONE
\doubleprooftrue
\setbox\proofbelow=\hbox\bgroup % NESTED TWO
\let\wereinproofbit\proofoverdbl
$\displaystyle
}%
%
%=============================================================================
\def\proofoverdots{% NESTED TWO
\eproofbit % NESTED ONE
\proofdotstrue
\setbox\proofbelow=\hbox\bgroup % NESTED TWO
\let\wereinproofbit\proofoverdots
$\displaystyle
}%
%
%=============================================================================
\def\proofusing{% NESTED TWO
\eproofbit % NESTED ONE
\setbox\proofrulename=\hbox\bgroup % NESTED TWO
\let\wereinproofbit\proofusing
\kern0.3em$
}

%=============================================================================
\def\endprooftree{% NESTED TWO
\eproofbit % NESTED ONE
% \dimen0 =     length of proof rule
% \dimen1 =     indentation of conclusion wrt rule
% \dimen2 =     new \shortenproofleft, ie indentation of conclusion
% \dimen3 =     new \shortenproofright, ie
%                space on right of conclusion to end of tree
% \dimen4 =     space on right of conclusion below rule
  \dimen5 =0pt% spread of hypotheses
% \dimen6, \dimen7 = height & depth of rule
%
% length of rule needed by proof above
\dimen0=\wd\proofabove \advance\dimen0-\shortenproofleft
\advance\dimen0-\shortenproofright
%
% amount of spare space below
\dimen1=.5\dimen0 \advance\dimen1-.5\wd\proofbelow
\dimen4=\dimen1
\advance\dimen1\proofbelowshift \advance\dimen4-\proofbelowshift
%
% conclusion sticks out to left of immediate hypotheses
\ifdim  \dimen1<0pt
\then   \advance\shortenproofleft\dimen1
        \advance\dimen0-\dimen1
        \dimen1=0pt
%       now it sticks out to left of tree!
        \ifdim  \shortenproofleft<0pt
        \then   \setbox\proofabove=\hbox{%
                        \kern-\shortenproofleft\unhbox\proofabove}%
                \shortenproofleft=0pt
        \fi
\fi
%
% and to the right
\ifdim  \dimen4<0pt
\then   \advance\shortenproofright\dimen4
        \advance\dimen0-\dimen4
        \dimen4=0pt
\fi
%
% make sure enough space for label
\ifdim  \shortenproofright<\wd\proofrulename
\then   \shortenproofright=\wd\proofrulename
\fi
%
% calculate new indentations
\dimen2=\shortenproofleft \advance\dimen2 by\dimen1
\dimen3=\shortenproofright\advance\dimen3 by\dimen4
%
% make the rule or dots, with name attached
\ifproofdots
\then
        \dimen6=\shortenproofleft \advance\dimen6 .5\dimen0
        \setbox1=\vbox to\proofdotseparation{\vss\hbox{$\cdot$}\vss}
        \setbox0=\hbox{%
                \kern\dimen6
                $\vcenter to\proofdotnumber\proofdotseparation
                        {\leaders\box1\vfill}$%
                \unhbox\proofrulename}%
\else   \dimen6=\fontdimen22\the\textfont2 % height of maths axis
        \dimen7=\dimen6
        \advance\dimen6by.5\proofrulebreadth
        \advance\dimen7by-.5\proofrulebreadth
        \setbox0=\hbox{%
                \kern\shortenproofleft
                \ifdoubleproof
                \then   \hbox to\dimen0{%
                        $\mathsurround0pt\mathord=\mkern-6mu%
                        \cleaders\hbox{$\mkern-2mu=\mkern-2mu$}\hfill
                        \mkern-6mu\mathord=$}%
                \else   \vrule height\dimen6 depth-\dimen7 width\dimen0
                \fi
                \unhbox\proofrulename}%
        \ht0=\dimen6 \dp0=-\dimen7
\fi
%
% set up to centre outermost tree only
\let\doll\relax
\ifwasinsideprooftree
\then   \let\VBOX\vbox
\else   \ifmmode\else$\let\doll=$\fi
        \let\VBOX\vcenter
\fi
% this \vbox or \vcenter is the actual output:
\VBOX   {\baselineskip\proofrulebaseline \lineskip.2ex
        \expandafter\lineskiplimit\ifproofdots0ex\else-0.6ex\fi
        \hbox   spread\dimen5   {\hfi\unhbox\proofabove\hfi}%
        \hbox{\box0}%
        \hbox   {\kern\dimen2 \box\proofbelow}}\doll%
%
% pass new indentations out of scope
\global\dimen2=\dimen2
\global\dimen3=\dimen3
\egroup % NESTED ZERO
\ifonleftofproofrule
\then   \shortenproofleft=\dimen2
\fi
\shortenproofright=\dimen3
%
% some space on right and flag we've just made a tree
\onleftofproofrulefalse
\ifinsideprooftree
\then   \hskip.5em plus 1fil \penalty2
\fi
}

%==========================================================================
% IDEAS
% 1.    Specification of \shiftright and how to spread trees.
% 2.    Spacing command \m which causes 1em+1fil spacing, over-riding
%       exisiting space on sides of trees and not affecting the
%       detection of being on the left or right.
% 3.    Hack using \@currenvir to detect LaTeX environment; have to
%       use \aftergroup to pass \shortenproofleft/right out.
% 4.    (Pie in the sky) detect how much trees can be "tucked in"
% 5.    Discharged hypotheses (diagonal lines).



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



%\pagestyle{empty}
\input{xy}
\xyoption{all}



\newcommand{\when}{\mbox{ \footnotesize \sc when }}





\newcommand{\tab}{\hspace*{4em}}
\newcommand{\tabbb}{\hspace*{3em}}
\newcommand{\tabb}{\hspace*{0.3in}}
\newcommand{\ptab}{\hspace*{0.1in}}
\newcommand{\ind}{\hspace*{1.5em}}

\newcommand{\rraw}{\longrightarrow}
\newcommand{\raw}{\rightarrow}
\newcommand{\Raw}{\Rightarrow}
\newcommand{\LRaw}{\Leftrightarrow}
\newcommand{\law}{\leftarrow}
\newcommand{\Law}{\Leftarrow}
\newcommand{\rimp}{\Longrightarrow}
\newcommand{\lrimp}{\Longleftrightarrow}
\newcommand{\limp}{\Longleftarrow}
\newcommand{\lraw}{\leftrightarrow}
\newcommand{\llraw}{\longleftrightarrow}
\newcommand{\lto}{\mapsto}
\newcommand{\nto}{\hookrightarrow}
\newcommand{\llto}{\longmapsto}
\newcommand{\dia}{\Diamond}
\newcommand{\summ}{\:+\:}
\newcommand{\pre}{\hat{\nex}}
\newcommand{\prev}{{\nex}^-}
\newcommand{\nex}{\raisebox{0.4mm}{\scriptsize $\bigcirc$}}
\newcommand{\epre}{{\Diamond}^-}
\newcommand{\apre}{{\Box}^-}
\newcommand{\rrarrow}{\longrightarrow}
\newcommand{\rarrow}{\rightarrow}
\newcommand{\ur}{ready(X,M,\_,R,L') \; +\;\mbox{\sf sublist(L,L')}}
\newcommand{\nur}{\;+\; \neg\, (\ur)}
\newcommand{\ev}[1]{\langle {#1} \rangle}

% \renewcommand{\[}{\mbox{\Large [ }}
% \renewcommand{\]}{\mbox{\Large ] }}
% \renewcommand{\)}{\mbox{\large ) }}
% \renewcommand{\(}{\mbox{\large ( }}



\def\AND     { \,\wedge\,                 }
\def\OR      { \,\vee\,                   }
\def\XOR     { \,\stackrel{.}{\vee}\,     }
\def\IMPLIES { \,\rightarrow\,            }
\def\IMPL    { \,\rightarrow\,            }
\def\IF      { \,\leftarrow\,             }
\def\IFF     { \,\leftrightarrow\,        }
\def\IFFdef  { \,\stackrel{\rm def}{\longleftrightarrow}\, }

\def\ANDdots { \,\wedge\!\ldots\!\wedge\, }
\def\ORdots  { \,\vee\!\ldots\!\vee\,     }

\def\is      { \!\setminus\!              }
\def\Forall#1{ \forall #1\                }
\def\Exists#1{ \exists #1\                }

\def\Na{\mbox{\rm I\hspace{-0.2em}N}}
\def\Nat{\mbox{\rm I\hspace{-0.2em}N}}
\def\Real{\mbox{\rm I\hspace{-0.2em}R}}
\def\Int{\mbox{\sf Z\hspace{-0.45em}Z}}
\def\Rat{\mbox{\rm\hspace{0.2em}\rule[.1ex]{.05em}{1.37ex}\hspace{-0.27em}Q}}
\def\Complex{\mbox{\rm\hspace{0.2em}\rule[.1ex]{.05em}{1.37ex}\hspace{-0.27em}C}}


\newcommand{\rif}[1]{\ref{#1} (pag.~\pageref{#1})}

\newcommand{\riif}[1]{\ref{#1}, pag.~\pageref{#1}}


\newcommand{\x}{\bar{\mbox{\sc x}}}
\newcommand{\y}{\bar{\mbox{\sc y}}}
\newcommand{\z}{\bar{\mbox{\sc z}}}
\newcommand{\w}{\bar{\mbox{\sc w}}}
\newcommand{\ttt}{\bar{\mbox{\sc t}}}
\newcommand{\bi}{\bar{\mbox{\sc b}}}
\newcommand{\ai}{\bar{\mbox{\sc a}}}


\newcommand{\sx}{\mbox{\sc x}}
\newcommand{\sy}{\mbox{\sc y}}
\newcommand{\sz}{\mbox{\sc z}}
\newcommand{\sk}{\mbox{\sc k}}
\newcommand{\spp}{\mbox{\sc p}}
\newcommand{\sj}{\mbox{\sc j}}
\newcommand{\sw}{\mbox{\sc w}}
\newcommand{\sbi}{\mbox{\sc b}}
\newcommand{\sai}{\mbox{\sc a}}
\newcommand{\snn}{\mbox{\sc n}}



\newcommand{\gu}{\mbox{\sc g}}
\newcommand{\co}{\mbox{\sc c}}
\newcommand{\te}{\mbox{\sc t}}
\newcommand{\bo}{\mbox{\sc b}}
\newcommand{\mo}{|\!\!\models}
\newcommand{\nmo}{|\!\!\not\models}







%\pagestyle{plain}
%\pagenumbering{arabic}

\newcommand{\orbar}{\ \big|\ }
\newcommand{\init}{\mbox{ \footnotesize \sc init }}
\newcommand{\stable}{\mbox{ \footnotesize \sc stable }}
\newcommand{\unless}{\mbox{ \footnotesize \sc unless }}
\newcommand{\needs}{\mbox{ \footnotesize \sc needs }}
%\newcommand{\needs}{\mbox{ $\Raw$ }}
\newcommand{\becausec}{\mbox{ \footnotesize \sc because\_c }}
\newcommand{\because}{\mbox{ \footnotesize \sc because }}
\newcommand{\lsto}{\mbox{ \footnotesize \sc leads\_to }}
 \newcommand{\oldcauses}{\mbox{ \footnotesize \sc causes }}
% \newcommand{\causesc}{\mbox{ \footnotesize \sc causes\_c }}
\newcommand{\causes}{\mbox{ \footnotesize \sc leads\_to }}
\newcommand{\causesc}{\mbox{ \footnotesize \sc leads\_to\_c }}
\newcommand{\inv}{\mbox{ \footnotesize \sc inv }}
\newcommand{\gop}{\mbox{ \footnotesize \sc op }}

\newcommand{\tcauses}{\mbox{\footnotesize \sc leads\_to}}
\newcommand{\tcausesc}{\mbox{\footnotesize \sc leads\_to\_c}}
\newcommand{\tinit}{\mbox{\footnotesize \sc init}}
\newcommand{\tstable}{\mbox{\footnotesize \sc stable}}
\newcommand{\tunless}{\mbox{\footnotesize \sc unless}}
\newcommand{\tbecausec}{\mbox{\footnotesize \sc because\_c}}
\newcommand{\tbecause}{\mbox{\footnotesize \sc because}}


\newcommand{\oikosadtl}{Oikos--{\em adtl\/} }
\newcommand{\comadtl}{Com$_adtl$}

%\newcommand{\minmodels}{\stackrel{min}{\models}}
\newcommand{\minmodels}{\models_{min}}


\newcommand{\mii}{\mbox{{\bf \sf m}$_{\mbox{\bf \sf i}}$} }
\newcommand{\mij}{\mbox{{\bf \sf m}$_{\mbox{\bf \sf j}}$} }
\newcommand{\mik}{\mbox{{\bf \sf m}$_{\mbox{\bf \sf k}}$} }
\newcommand{\mI}{\mbox{{\bf \sf m}$_{\mbox{\bf \sf 1}}$} }
\newcommand{\mII}{\mbox{{\bf \sf m}$_{\mbox{\bf \sf 2}}$} }

\newcommand{\mm}{\mbox{{\bf \sf m}} }
\newcommand{\tmm}{\mbox{{\bf \sf m}}}
\newcommand{\tmn}{\mbox{{\bf \sf n}}}
\newcommand{\mn}{\mbox{{\bf \sf n}} }
\newcommand{\moo}{\mbox{{\bf \sf o}} }

\newcommand{\mbb}{\mbox{{\bf \sf b}} }
\newcommand{\mtt}{\mbox{{\bf \sf t}} }
\newcommand{\muu}{\mbox{{\bf \sf u}} }

\newcommand{\tmii}{\mbox{{\bf \sf m}$_{\mbox{\bf \sf i}}$}}

\newcommand{\bari}{\bar{\mbox{{\bf \sf m}}}_{\mbox{\bf \sf i}}}


\newcommand{\bank}{\mbox{{\bf \sf bank}} }
\newcommand{\user}{\mbox{{\bf \sf user}} }









\begin{document}


\title{Distributed States Temporal Logic} 


\author{Carlo Montangero \quad Laura Semini}

\institute{Dipartimento di Informatica, Universit\`a di Pisa.
\\
\{monta, semini\}@di.unipi.it}



\maketitle

\begin{abstract}
 We introduce a temporal logic to reason on global applications in an
asynchronous setting.  First, we define the Distributed States Logic
(DSL), a modal logic for localities that embeds the local theories of
each component into a theory of the distributed states of the
system. We provide the logic with a sound and complete
axiomatization. The contribution is that it is possible to reason
about properties that involve several components, even in the absence
of a global clock.  Then, we define the Distributed States Temporal
Logic (DSTL) by introducing temporal operators \`a la Unity.  We
support our proposal by working out a pair of examples: a simple
secure communication system, and an algorithm for distributed leader
election.


The motivation for this work is that the existing logics for
distributed systems do not have the right expressive power to reason
on the systems behaviour, when the communication is based on
asynchronous message passing. On the other side, asynchronous
communication is the most used abstraction when modelling global
applications.
\end{abstract}





\section{Introduction}

The current trend towards global computing needs software that works
in an open, concurrent, distributed, high--latency, security--sensitive
environment. Besides, this software must be reliable, scalable, and
``shipped today''.
Several trends are emerging in response to the challenges involved in
the development of software with so demanding requirements.

On one side, there is an increasing interest in the seamless
integration of asynchronous communication in programming,
coordination, and specification languages, since message--passing,
event--based programming, call--backs, continuations, dataflow models,
workflow models etc. are ubiquitous in global computing. Notable
examples in this direction can be found in the context of the
Microsoft .NET initiative, like the introduction of support for the
delegate--based asynchronous calling model in the libraries of the
Common Language Runtime~\cite{CLR2}, and the proposal of $chords$ in
Polyphonic C\# to accommodate asynchronous methods in
C\#~\cite{CSHARP}.  We provide an example of
coverage of asynchronous communication in coordination and
specification languages in~\cite{sgarrascico}.

Another significant trend is represented by Component--Oriented
Programming, that aims at producing software components for a software
market and for late composition. Composers are third parties, possibly
the end user, who are not able nor willing to modify components. This
trend emphasizes the need for high quality specifications that put the
composer into the position to decide what can be composed under which
conditions. In a previous work with
\oikosadtl\cite{coord99c,fmics01}, a specification language for
distributed systems based on asynchronous communications, we showed
how to accommodate asynchronous communication in the composition of
distributed systems specifications.

A notable example of component programming in the context of global
computing is offered by the Web Services~\cite{Kreger}, which leverage
the standard representation of data provided by XML to foster the
construction of new components (services) by the coordination of other
services. Since the cooperation is based on asynchronous protocols,
this is also an example of the convergence of asynchronous
communications and component programming.


Formal methods can play a major role in global computing. Precisely
because the actors are programmatically independent, they need to have
reliable ways to share precise knowledge of the artifacts they use or
produce, independently of the particular technology (programming
languages, middleware, \dots) they rely on. Formal methods offer
exactly this kind of independence and precision, since they provide
abstract models to share when operating or developing with
components.  They can provide ways to make precise the specifications
of the components and of their contextual dependencies, and to prove
in advance global properties, i.e.  that a composition will meet the
specifications it addresses.

\

\noindent 
In this paper we define DSTL (Distributed States Temporal Logic), an
extension of temporal logic to deal with distributed systems.
In~\cite{time02} we defined new modalities to name system
components. Here, we introduce the operators to causally relate
properties which might hold in distinguished components, in an
asynchronous setting.  A typical DSTL formula is:
\begin{eqnarray}
&&\mm  \,p \; \causes \; \mn  \,q \wedge \moo \, r \label{ex:intro}
\end{eqnarray}

%\vspace{-0.2cm}

\noindent 
where the operator $\tcauses$ is similar to Unity's $\lto$ (leads
to)~\cite{chmi88}, and \tmm, \tmn, and \moo express locality.
Formula~(\ref{ex:intro}) says that a property $p$ holding 
in component $m$, causes properties $q$ and $r$ to hold in future
states of components $n$ and $o$, respectively. An example is the
computation below. Horizontal arrows denote the sequence of states of
a component, oblique arrows denote the communications.


\vspace{-0.2cm}

\hspace{0.9cm}
 \xymatrix@R-=1pt{
 &&&&&&&&\\
  {(n)}& \ar@{.>}[r] &   \ar@{.>}[rr]  && 
                 \ar@{.>}[rrr] 
                 && &  {q} \ar@{.>}[r] & \\ 
  {(m)}&  \ar@{.>}[r] &  {p} \ar@{.>}[r] &  \ar@{.>}[rd]  
                  \ar@{.>}[rr]&& \ar@{.>}[r]  &
                                 \ar@{.>}[rr]\ar@{.>}[ru] & & &\\  
  {(o)}&  \ar@{.>}[rrr] &  &&  \ar@{.>}[rr] &&
         {r}\ar@{.>}[rr] &&& 
 }

\vspace{0.2cm}


\noindent
At this point a short philosophical note is needed. We tend to think
that our operators express {\em causality}, even though, strictly
speaking, they only define temporal relations, i.e. that their
consequences (right hand side operands) hold {\em after} (or before,
with past operators) their premises (left hand side operands).  In
fact, in our models, a state in a component is after one in another
component only if there has been a communication between the two.
Philosophically, this may not entail a causal relation, but our goal
is to specify systems: it is natural to think that the communication
carries the information needed to cause the intended effect.  It is in
this sense that we use the term causality.

A similar argument applies locally: the implementation will take care
that a state satisfying the consequences is reached, after one
satisfying the premises.



\vspace{0.5cm}

\noindent
From a technical point of view, the usual choices to build a Kripke
model for formulae like~(\ref{ex:intro}) are to consider the set of
worlds $W$ to be one of the following:
\begin{enumerate}
\item the set of the  states of a computation, i.e. the union of
all the states of the system components, like the circles in the
following figure.


\vspace{-0.2cm}

\hspace{0.9cm}
 \xymatrix@R-=2pt{
 &&&&&&&&\\
 {(m)}&{\bigcirc} \ar@{.>}[r] &  {\bigcirc} \ar@{.>}[rd]   
	\ar@{.>}[rr]  && {\bigcirc}
                 \ar@{.>}[rrr] 
                 && &  {\bigcirc}  \ar@{.>}[r] & \\ 
 {(n})&{\bigcirc}  \ar@{.>}[r] & {\bigcirc} \ar@{.>}[r] & {\bigcirc}
                  \ar@{.>}[rr]&&{\bigcirc} \ar@{.>}[r]  &{\bigcirc}
                                 \ar@{.>}[rr]\ar@{.>}[ru] & & &\\  
 }


\vspace{0.3cm}

\noindent
This choice was adopted in \oikosadtl and has shown some
problems.  For instance, consequence weakening, or, more in general,
the possibility of reasoning on logical relations between formulae
like the premises or the consequences of~(\ref{ex:intro}), is not part
of the logic.  In particular, a formula like

\vspace{-0.8cm}

\begin{eqnarray}
&&(\mn \,q \wedge \mm \,r) \raw \mn \,q \label{ex:intro2}
\end{eqnarray}

\vspace{0.3cm}

\noindent 
which would permit to weaken the consequences of~(\ref{ex:intro})
would not be a legal formula, since no world can satisfy the conjunction
$\mn \,q \wedge \mm \,r$.


\item the set of global states, or snapshots, of the system, where
each world is a tuple of states, one for each component. These tuples must
satisfy some constraints to be coherent with the communications
between the subsystems. In the figure below, examples of worlds are
$\langle s_m^i ,\,s_n^j\rangle^{i=0,1}_{0\leq j \leq 2}$, while $\langle s_m^2
,\,s_n^1\rangle$ would not be a legal world.


\vspace{-0.2cm}

\hspace{0.9cm}
 \xymatrix@R-=6pt{
 &&&&&&&&\\
 {(m)}&{s_m^0}   \ar@{.>}[r] &  {s_m^1} \ar@{.>}[dr]
\ar@{.>}[rr]  && \ar@{.>}[dr]{s_m^2} 
                 \ar@{.>}[rrr] 
                 && &  {s_m^3}  \ar@{.>}[r] & \\ 
 {(n)}&{ s_n^0}  \ar@{.>}[r] & { s_n^1}  
\ar@{.>}[r] &  { s_n^2}   
                  \ar@{.>}[rr]&&  { s_n^3} \ar@{.>}[r]  &{ s_n^4}
                                 \ar@{.>}[rr]\ar@{.>}[ru] & & &\\  
 }

\vspace{0.3cm}

\noindent 
This choice, adopted in many logics for distributed systems (see
Section~\ref{discussion}) is not applicable in the case of
asynchronous communication. Think of the case of property $p$ holding
{\em only} in state $s_m^1$ and $q$ holding {\em only} in states
$s_n^j$, for $0\leq j \leq 4$. The formula 
\vspace{-0.8cm}

\begin{eqnarray}
&&\mm \,p \raw   \mn \,q \label{ex:intro3}
\end{eqnarray}

\vspace{-0.2cm}

\noindent
would be valid in the model, inferring a remote instantaneous
knowledge which is meaningless in an asynchronous setting. Moreover,
it would be natural to say that world $\{s_m^2,\, s_n^3\}$ follows
$\{s_m^1,\,s_n^2\}$. In this case, one could assert that $\mn \,p
\causes \mm \,q$ holds, if $p$ and $q$ hold in $s_n^2$ and $s_m^2$,
respectively, even though not even a temporal relationship exists
between these two states.


\item a third possibility would be to consider all the $k$--tuples of
states (where $k$ is the number of the system components) as
worlds. But then, formula~(\ref{ex:intro3}) would be valid in the
model above if $q$ holds in all the states of component $n$. Even if
this is philosophically more acceptable, we claim that a better
solution can be found. What is more, this choice is not
adequate since if we let $p$ and $q$ hold in $s_m^1$ and $s_n^2$,
respectively, we would like the computation above to be a model for
$\mm \,p \causes \mn \,q$. On the contrary, world $\{s_m^1,\,s_n^3\}$
satisfies the premise but is not followed by any state satisfying the
consequence. 

\end{enumerate}


\noindent
The first contribution of our work is to introduce the distributed
state logic DSL, that carries over all meaningful propositional rules,
like {\em and} simplification, so that they can be exploited
orthogonally to any temporal operator.  A major consequence of the
introduction of DSL is that the exploitation of the local theories in
the proofs of the distributed properties becomes smooth and
robust. 

The second part of the paper defines DSTL: we add the temporal
operators, and the corresponding derivation rules.  The semantic
domain of DSL, the power--set of the set of all system states, even if
chosen for technical reasons, makes the full logic DSTL a very
expressive language, that meets the pragmatic expectations of a
designer fully (see Section~\ref{discussion} for a discussion).  The
achievement is that it is possible to reason about properties that
involve several components, even in the absence of a global clock, the
typical assumption in an asynchronous setting.



Section \ref{DSL} introduces the modal logic DSL, and its sound and
complete axiomatization.  Section \ref{logics} defines DSTL as an
extension of DSL with the temporal operators.  Sections \ref{example}
and \ref{example2} work out a pair of examples: a simple secure
communication system, and an algorithm for the leader election
problem. The last sections cover a discussion of the main design
issues, related work and future perspectives.



\section{DSL}
\label{DSL}





We assume a countable set of propositional letters $P$, with $p, q,
 \ldots$ ranging over $P$.  The DSL well--formed formulae over a
 finite set of components $\Sigma = \{m_1, m_2, \ldots, m_k\}$ are
 defined by:
\begin{eqnarray*}
F & \ :: = \ & p \orbar \bot \orbar \sim F \orbar F\wedge F^\prime
\orbar \mii F
\end{eqnarray*}

\noindent
where $\bot$ is the propositional constant {\em false}, and \mii for
$i=1\ldots k$ are  unary location operators.   With $\bari$ we
denote the dual of \tmii, i.e., $\bari F \equiv \,\sim \mii   \sim
F$. With $\top$ we denote {\em true}, i.e. $\top \equiv \:\sim \bot$.



\subsection{Semantics} 
A model ${\cal M}$ for DSL formulae is a tuple $(W, R_{1}, 
\ldots,R_{k}, V)$. Let $u,\, v,\, w$ range over $W$, the
reachability relations $R_i$ satisfy the following conditions:
\begin{eqnarray}
(u,\, v) \in R_i   & \mbox{ }\quad \raw \quad \mbox{ } 
& (v,\, v) \in R_i  \label{rc1}\\
(u,\, v) \in R_i   & \raw &  (v,\, w) \in R_i \raw v=w 
\quad \quad\quad \quad \mbox{ }\label{rc2}\\
(u,\, v) \in R_i   & \raw &  \not\exists w.\: (v,\, w) \in R_j \mbox{ for } j\neq i \label{rc3}
\end{eqnarray}


\noindent
To help the intuition, $W$ can be thought as having $k$ disjoint
subsets of worlds: we call these worlds {\em leaves}. Whenever $(u,\, v) \in
R_i$, then $v$ is a leaf for relation $R_i$, namely an {\em i--leaf}.
Condition~(\ref{rc1}) says that $R_i$ is reflexive on {\em i--leaves},
conditions~(\ref{rc2}) and~(\ref{rc3}) say that {\em i--leaves} are
actually leaves: no other world can be reached.  An example model is
in Section~\ref{anexamplemodel}, where the {\em i--leaves} are
singleton sets, having as unique element a state of component $m_i$.

\

\noindent
The semantics of the DSL formulae is given by:
\begin{eqnarray*}
&&({\cal M}, \, u) \models \top  \\
&&({\cal M}, \, u) \models p   \ \mbox{ iff } \ p\in V(u)\\
&&({\cal M}, \, u) \models \, \sim F   \ \mbox{ iff } \mbox{ not }  ({\cal M}, \, u) \models F\\
&&({\cal M}, \, u) \models F  \wedge F'  \ \mbox{ iff } \ ({\cal M}, \, u) \models F  \mbox{ and }   ({\cal M}, \, u) \models F' \\
&&({\cal M}, \, u) \models \mii F   \ \mbox{ iff } \ \exists  v.\; (u, v)\in R_{i} 
\; \mbox{and}\;  ({\cal M}, \, v) \models F
\end{eqnarray*}




\subsection{Axiom system} \label{dslaxsys}
  We propose the following axiomatization for
DSL. For the sake of readability, we use $\mm$ and  $\mn$, with $\mm\neq
\mn$, instead of  $\mii$ and  $\mij$. 

\

%\noindent
$\begin{array}{ll}
{\bf PC}  &  \mbox{axioms of the propositional calculus}\\
{\bf K}  & \bar{\mm} (F\raw F') \ \raw \ (\bar{\mm}F \raw \bar{\mm} F')\\
{\bf DSL1}   & \bar{\mm} (\bar{\mm}F \lraw F) \\
{\bf DSL2}  \ \  &  \bar{\mm}  \bar{\mn} \bot \\
{\bf MP} & \ {\small \prooftree F \quad F\raw F' \justifies F' \endprooftree}
\quad \quad {\bf Nec } \ \  {\small \prooftree F \justifies \bar{\mm}F \endprooftree}
 \end{array}
$



\vspace{0.2cm}

\begin{theorem} The DSL axiom system is sound and complete. 


\vspace{0.2cm}


\noindent
{\bf Proof.} The soundness of the axioms is easy to see. We prove
completeness.

 Let $(W^{DSL}, R_{1}^{DSL}, \ldots,R_{k}^{DSL},
V^{DSL})$ be the canonical model for DSL: worlds in
$W^{DSL}$ are maximal consistent sets of DSL formulae ({\sc dsl--mcs}
in the following), and  $(u,v)\in R_{i}^{DSL}$ if and only if
$\bar{\mii} F \in u \; \raw \; F \in v$.  We need to show
that, for all $i$, $R_{i}^{DSL}$ satisfies
conditions~(\ref{rc1})--(\ref{rc3}).

\vspace{-0.3cm}


\begin{description} 
\item[{\rm \em Cond. (\ref{rc1}):}]  we prove that    $(u,v)\in
R_{i}^{DSL} \; \raw \; (v,v)\in 
R_{i}^{DSL}$
\\
Suppose $\bar{\mii} F \in v$. $u$ is a {\sc dsl--mcs} and hence (see
DSL1) $ \bar{\mii} (\bar{\mii}F \raw F)  \in u$.  But $(u,v)\in
R_{i}^{DSL}$, hence  $ \bar{\mii}F \raw F \in v $. Thus, by modus
ponens, $F\in v$.

\item[{\rm \em Cond.  (\ref{rc2}):}] we prove that $(u,v)\in
R_{i}^{DSL}$ and $(v,w)\in 
R_{i}^{DSL}$ imply $v=w$ 
\\ 
It is sufficient to prove  that $v\subseteq w$. In fact, $v$ and $w$ are  
{\sc dsl--mcs} and it is not the case that $v
\subset w$, thus $v=w$. 
Let $F\in v$. $u$ is a {\sc dsl--mcs} and hence (see
DSL1) it includes $ \bar{\mii} (F \raw \bar{\mii}F)$. But $(u,v)\in
R_{i}^{DSL}$, hence  $ F \raw \bar{\mii} F \in v $. 
Thus, by modus
ponens, $\bar{\mii} F\in v$. As $(v,w)\in R_{i}^{DSL}$, we conclude
that $F\in w$. 

\item[{\rm \em Cond.  (\ref{rc3}):}] we prove that $(u,v)\in
R_{i}^{DSL}$ implies 
$\not\exists w. $ $(v,w)\in R_{j}^{DSL}$, for $j\neq i$ 
\\ 
Assume $(v,w)\in R_{j}^{DSL}$.  As $u$ is a {\sc dsl--mcs}, it
includes $\bar{\mii}\bar{\mij} \bot$ (DSL2). As $(u,v)\in R_{i}^{DSL}$, then
$\bar{\mij} \bot \in v$.  As $(v,w)\in R_{j}^{DSL}$, then $\bot \in w$,
which is an absurd. \mbox{ }\hfill $\Box$

\end{description}

\end{theorem}




\begin{example} \label{toprove}
The following formulae can be derived. Formulae are followed by the
list of axioms or rules used in their proof. The proofs are in the
appendix.



\

%\noindent
$\begin{array}{lll}
{\bf axiom \; 4} \ & \bar{\mm} F \ \raw \ \bar{\mm}\bar{\mm}F & [DSL1,K]\\
 {\bf D1} & \mm\mm F \lraw \mm F \quad\quad \quad\quad\quad\quad\quad\quad& [DSL1,K,PC]
% \end{array}$
\\
% $\begin{array}{lll}
 {\bf D2} \quad\quad & \mm (F\wedge F') \raw(\mm F\wedge \mm F') & [PC,Nec,K]\\
 {\bf D3} & \bar{\mm}(F\raw F') \ \raw \ (\mm F \raw \mm F^\prime)
& [Nec,K,MP,PC] \\ 
{\bf D4} & \bar{\mm} F \raw (\mm \top \raw \mm F ) & [D3] \\
 {\bf D5}  & \bar{\mm} (\mm F \lraw F)  & [DSL1,PC] \\
 {\bf D6} &  ( \bar{\mm} (F\raw F') \wedge  \bar{\mm}
(F'\raw F'') )\raw  \bar{\mm} (F\raw F'') \quad\quad\quad & [Nec,K]\\
 {\bf D7}  & \mm (F\vee F' )\lraw (\mm F \vee \mm F') & [D3,Nec,K,PC]\\
 {\bf D8}  & \bar{\mm} ((\mm F\wedge \mm F')\raw \mm (F\wedge F')) &
[D5,D6,D7,Nec,K]\\

 \end{array}$



\end{example}



\subsection{A frame of distributed states} 
\label{anexamplemodel} 

\noindent
Let $S_{i}$ be the set of states of component $m_i$, with $S_{i}\cap
S_{j}= \emptyset$ for $i\neq j$, $S = \bigcup^{i=1,}_{k} S_{i}$, $DS =
2^{S}$, and $ds,\, ds'\in DS$.  Let $(ds, ds')\in R_{i}$ if and only
if $ds'$ is a singleton set $\{s\}$, with $s\in S_{i} \cap ds$. The
frame $(DS, R_{1}, \ldots,R_{k})$, satisfies
conditions~(\ref{rc1})--(\ref{rc3}) above. We call these frames
{\em frames on} $DS$, and call $DS$ the set of {\em distributed states},
from which the name of the logic DSL. The frames on $DS$ play a
central role in the paper, since they are used to build the models for
DSTL formulae.  

Some examples follow.
 





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
\begin{example}\label{Frame}
Let the set $DS$ be built on $S_1 = \{s, s^{\prime}\}$ and $S_2 =
\{s^{\prime\prime}\}$, then the frame on $DS$ can be
represented as:

\vspace{-0.7cm}

{\small
\mbox{ } \quad \quad\quad \quad \quad\quad \quad \quad\quad \mbox{ }  
\xymatrix@R-=10pt@C-=6pt{
&&&&&&\\
         && & \{s,s^{\prime\prime}\}\ar[dl]^{R_1}\ar[dr]_{R_2} 
        &&&   \\
& & \{s\}\ar@(ur,ul)[]_{R_1} &&  \{s^{\prime\prime}\}\ar@(ur,ul)[]_{R_2} &&\\
\{s,s^{\prime}\}\ar[urr]_{R_1}\ar[ddrrr]_{R_1}
&&& 
 \{s,s^{\prime},s^{\prime\prime}\}\ar[dd]_{R_1}\ar[ul]_{R_1} \ar[ur]^{R_2}&&&
\{s^{\prime},s^{\prime\prime}\}\ar[ull]^{R_2}\ar[ddlll]^{R_1}\\
&&&&&&\\
&&&  \{s^{\prime}\}\ar@(dl,dr)[]_{R_1} &&&\\
&&&&&&\\
}
}

\end{example}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5

\begin{note}
For the sake of readability, when we use $\mm$ and $\mn$, we also use
$S_m$, and $S_n$.
\end{note}

\begin{example}
If we take $s\in S_m$, $s^\prime \in S_n$


\vspace{-0.2cm}

\hspace{2.2cm}
 \xymatrix@R=2pt{
 &&&&&&&\\
 {(m)}& \ar@{.>}[rrr] &&& {s} \ar@{.>}[rrr] &&& \\
 {(n)}&  \ar@{.>}[rrrr] &&&& {s^\prime}  \ar@{.>}[rr] && \\
 }


\vspace{0.2cm}

\noindent
with $V(\{s\})=\{p\}$, $V(\{s^\prime\})=\{q\}$, then the distributed state
$\{s,s^\prime\}$ satisfies $\mm p \wedge \mn q$.

\end{example}


\begin{example}
The implication $\mm (F \wedge F') \raw \mm F \wedge \mm F'$ holds,
while the converse does not. Indeed, for $ds = \{s, s'\} \subseteq
S_m$

\vspace{-0.2cm}

\hspace{2.2cm}
 \xymatrix@R=2pt{
 &&&&&&&\\
 {(m)}& \ar@{.>}[rr] && {s}\ar@{.>}[rr] && {s^\prime} \ar@{.>}[rr] && \\
 }

\vspace{0.2cm}

\noindent
and $V(\{s\}) = \{p\}$, $V(\{s'\}) = \{q\}$, we have $ds\models
\mm p \wedge \mm q$, but not $ds\models \mm \, (p \wedge q)$.  With an
eye to the full logic DSTL, this non--equivalence is useful to specify
that an event can have different future effects in a component,
without constraining them to occur in the same state (see
Section~\ref{discussion} for further discussion).



\end{example}

\begin{example}
The formula $\mm \mn F$ is false. In fact, $ds \models \mm \mn F$ if
and only if there exists an $s\in S_{n} \cap S_{m} \cap ds$ such that
$\{s\} \models F$, but no such $s$ can exist since $S_{m}$ and $S_{n}$
are disjoint. Conversely, $\mm \mm F$ is satisfiable, and it is
equivalent to $\mm F$.
\end{example}

\begin{example}
The formula  $\mm \top$ is satisfied by all the distributed states
$ds$ such that  $ds \cap S_{m} \neq \emptyset$. 
\end{example}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{DSTL}
\label{logics}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



DSTL extends DSL adding temporal operators.  Formulae are built as
follows:

\vspace{-0.5cm}

\begin{eqnarray*}
\phi & \ :: = \ & F \orbar F\: \causes \: F^\prime  \orbar F\:
\because \: F^\prime  \orbar F\: \causesc \: F^\prime  \orbar F\:
\becausec \: F^\prime  \orbar  \\
&&F\: \unless \: F^\prime \orbar \init F
\end{eqnarray*}




\vspace{-0.1cm}

\noindent
where $F,\, F'\in DSL$.  Operator $\tcauses$ expresses a liveness
condition, and is similar to Unity's $\lto$ (leads to): $F$ is surely
followed by $F'$.  Operator $\tbecause$ expresses a safety condition, and
says that $F$ must be preceded by $F^\prime$.

Suffix {\footnotesize \sc c} stands for {\em closely}, $\tcausesc$
requires formula $F'$ to hold in the distributed states in which $F$
holds, or in the next ones. Dually, $\tbecausec$ says that $F'$ must hold
in the states immediately preceding those satisfying $F$, or in the
same ones.

Operator $\tunless$ extends Unity's $\tunless$, and $\tinit$ permits to
describe the initial state. A special case of $\tunless$ is stability:

$$ \stable F \stackrel{def}{=} \, F \unless \bot$$




\subsection{Semantics} 
\label{logics.semantics}

The models for DSTL formulae are built on structures like the one in
the following figure, which describes the computation of a system with
three components ($m,\, n,\, o$).  We call $s_m^{i}$ the $i^{th}$
state of component $m$. We call $ds^0$ the set of the
initial states $\{s^0_m, s^0_n, s^0_o\}$.


\vspace{-0.2cm}

\hspace{0.5cm}
 \xymatrix@R-=2pt{
 &&&&&&&&\\
 {(m)}& {s_m^0} \ar[r] & {s_m^1} \ar[rd] \ar@{.>}[rr]  &&  {s_m^6}
                 \ar@{.>}[rrr] 
                 && &  {s_m^{12}} \ar@{.>}[r] & \\ 
 {(n)}& {s_n^{0}}  \ar[r] &  {s_n^{2}}\ar[r] &  {s_n^{3}}
                  \ar@{.>}[rr]&&{s_n^{7}}\ar@{.>}[r] \ar[rd]  &{s_n^{15}}
                                 \ar@{.>}[rr]\ar[ru] & & &\\  
 {(o)}& {s_o^{0}}  \ar@{.>}[rrr] &  && {s_o^{5}} \ar@{.>}[rr] &&
         {s_o^{8}}\ar@{.>}[rr] &&& 
 }

\

\noindent
In the figure, plain arrows denote atomic state
transitions and communications, dotted arrows denote sequences of
them.


\begin{definition} {($R, \; R^=, \; R^*$)}


\noindent
State transitions and communications define a next state relation $R$,
where $(s,s')\in R$ if and only if $s$ and $s'$ are states of the same
component, with $s'$ immediately following $s$, or if there is a
communication from $s$ to $s'$. For example, in the computation above,
$(s_m^0,s_m^1),\, (s_m^1,s_n^{3}),\, (s_n^{2},\, s_n^{3})\in R$. The
plain arrows between pairs of states denote relation $R$.

We call $R^=$ the reflexive closure of $R$, and $R^*$ its reflexive
and transitive closure.  For example, in the computation above,
$(s_m^0,s_m^1),\, (s_m^0,s_n^{3}),\, (s_m^1,s_n^{3}),\, (s_n^{2},\,
s_m^{12})\in R^*$.  We say that $s'$ causally depends on $s$ when
$(s,s')\in R^*$. Causal dependency has to be read as the partial order
relationship between states of a distributed computation, defined by
state transitions and communications~\cite{lamport78}. If
neither $(s,s')\in R^*$ nor $(s',s)\in R^*$, states $s$
and $s'$ are concurrent.



\end{definition}



\begin{definition} {(Models, $\leq,\; \leq_c$)}

 \noindent
A model ${\cal M}$  is a tuple $(DS, R_{1},
\ldots,R_{k}, \leq, \leq_c, V)$, where:
\begin{eqnarray*}
 ds \leq ds^{\prime} & \  {\rm iff} \ &   \forall s\in ds, \: \exists
s^{\prime}\in ds^{\prime}.\; (s, s^{\prime})\in R^* 
 \  {\rm and} \ 
\forall s^{\prime}\in ds^{\prime}, \: \exists s\in ds.\; (s, s^{\prime})\in R^*
\\
 ds \leq_c ds^{\prime} & \  {\rm iff} \ &   \forall s\in ds, \: \exists
s^{\prime}\in ds^{\prime}.\; (s, s^{\prime})\in R^=
 \  {\rm and} \ 
\forall s^{\prime}\in ds^{\prime}, \: \exists s\in ds.\; (s, s^{\prime})\in R^=
\end{eqnarray*}

\noindent
We also  ask that the valuation function
$V: DS\raw 2^{P}$ satisfies $V(ds)= \bigcap_{s\in ds} V(\{s\})$.


\end{definition}


\begin{definition} \label{DSTLsemantics} {(Semantics)}


\noindent
Let ${\cal M}$ be a model, and $ds^0$ the set
of its initial states. We define:

\

$\begin{array}{lcl}
{\cal M} \models_T F 
      &  \quad {\rm iff}  \quad  &
	\forall  ds.\: ds\models F \\
{\cal M} \models_T F \causes  F^\prime  &   {\rm iff} &
         \forall  ds.\: ds \models F
        \mbox { implies } 
         \exists \: ds^{\prime} \geq ds.\;
          ds^{\prime} \models F^\prime\\
{\cal M} \models_T F \because  F^\prime  &   {\rm iff} &
         \forall  ds.\: ds \models F
        \mbox { implies } 
         \exists \: ds^{\prime} \leq ds.\;
          ds^{\prime} \models F^\prime\\
{\cal M} \models_T F \causesc  F^\prime  &   {\rm iff} &
         \forall  ds.\: ds \models F
        \mbox { implies } 
         \exists \: ds^{\prime} \geq_c ds.\;
          ds^{\prime} \models F^\prime\\
{\cal M} \models_T F \becausec  F^\prime  &   {\rm iff} &
         \forall  ds.\: ds \models F
        \mbox { implies } 
         \exists \: ds^{\prime} \leq_c ds.\;
          ds^{\prime} \models F^\prime\\
{\cal M} \models_T F \unless  F^\prime  &   {\rm iff} &
         \forall  ds.\: ds \models F
        \mbox { implies } \exists  ds^{\prime} \geq_c ds. \\
	&& \quad\quad ( ds^{\prime} \not\supseteq ds \: 
	\wedge\:    ds^{\prime} \models F) \ \vee \ ds^{\prime} \models
	F^\prime\\
{\cal M} \models_T  \init  F  &   {\rm iff} &
          ds^0 \models F
 \end{array}
$

\

\noindent
where $\models$ is the DSL satisfiability relation. 

The next section discusses this definition using some examples. In
particular, the side condition $ ds^{\prime}\not\supseteq ds $ for
$\tunless$ is illustrated in Example~\ref{ex:subset}.

\end{definition}




\subsection{Examples}

To exemplify the definition of the DSTL semantics, we choose some
formulae and discuss whether they are satisfied or not by a model
${\cal M}$ (a computation of a system made up of two components, $m$
and $n$). In the examples we can only present the initial fragments,
the discussion on satisfiability is done with respect to the given
fragment. From now on, we label the states with the predicates holding
in them instead of a name. 

We recall that, according to the definition in Section~\ref{DSL}, a
distributed state is any set of states. This means that when we have
to check a condition like $\forall ds \ldots \exists ds' \ldots$, we
need to consider all possible sets of states as $ds$. This may lead to
counter-intuitive choices, like picture (c) of
Table~\ref{tabex} to reason on the first formula of
Example~\ref{ex:temp}. We consider these choices in the examples to
clarify the semantic details. However, the specifier can be safely
guided by the natural interpretation of the operators. Anyhow, our
definition of distributed state is exactly what was needed to overcome
the problems with the existing models, as discussed in the
introduction.








\begin{table} \label{tabex}

\mbox{}\hrule\mbox{}

\

\

 \xymatrix@R-=1pt@C-=16pt{ 
{(m)}& {p} \ar[r] & {q} \ar[rd]
 \ar@{.>}[rr] && {r} \ar@{.>}[rrr] && & *+[F]{u,z} \ar[r] & {z}
 \ar@{.>}[r] & {z} \ar@{.>}[r] & && {\;\:(a)}\\ 
{(n)}& {p,t} \ar[r] & {u}\ar[r] &
 {v} \ar@{.>}[rr]&& {p,u} \ar@{.>}[r] & *++[o][F]{w,t}
 \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] &&& } 

\

\

%%%% b

 \xymatrix@R-=1pt@C-=16pt{
 {(m)}& {p} \ar[r] & {q} \ar[rd] 
	\ar@{.>}[rr]  &&  
	*++[o][F-]{r}      \ar@{.>}[rrr] 
                 && &  
	*+[F]{u,z} \ar[r] & {z} \ar@{.>}[r] & {z} \ar@{.>}[r] & && (b)\\ 
 {(n)}& {p,t}  \ar[r] &  
	{u}\ar[r] &  
	{v}  \ar@{.>}[rr]&&
	*++[o][F-]{p,u} \ar@{.>}[r] &
	{w,t}     \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] & &&
}

\

\

%%%% c

 \xymatrix@R-=1pt@C-=16pt{
 {(m)}& {p} \ar[r] & {q} \ar[rd] 
	\ar@{.>}[rr]  &&  
	{r}      \ar@{.>}[rrr] 
                 && &  
	*+[F]{u,z} \ar[r] & 
	*++[o][F-]{z} \ar@{.>}[r] & *+[F]{z} \ar@{.>}[r] & && (c)\\ 
 {(n)}& {p,t}  \ar[r] &  
	{u}\ar[r] &  
	{v}  \ar@{.>}[rr]&&
	*++[o][F-]{p,u} \ar@{.>}[r] &
	{w,t}     \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] & &&
} 

\

\

%%%%%%%%% d

 \xymatrix@R-=1pt@C-=16pt{ 
 {(m)}& *++[o][F-]{p} \ar[r] & {q} \ar[rd] 
	\ar@{.>}[rr]  &&  
	{r}      \ar@{.>}[rrr] 
                 && &  
	*+[F]{u,z} \ar[r] & {z} \ar@{.>}[r] & {z} \ar@{.>}[r] &&& {\;\:(d)}\\ 
 {(n)}& {p,t}  \ar[r] &  
	{u}\ar[r] &  
	*++[o][F-]{v}  \ar@{.>}[rr]&&
	{p,u} \ar@{.>}[r] &
	  *+[F]{w,t}     \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] & &&
} 

\

\

%%%%%%%% e era f
 \xymatrix@R-=1pt@C-=16pt{ 
 {(m)}& {p} \ar[r] & *++[o][F-]{q} \ar[rd] 
	\ar@{.>}[rr]  &&  
	{r}      \ar@{.>}[rrr] 
                 && &  
	{u,z} \ar[r] & {z} \ar@{.>}[r] &  *+[F]{\bigcirc\!\!\!\!\!z\;}
 \ar@{.>}[r] & && {\!\!\!(e)} \\  
 {(n)}& {p,t}  \ar[r] &  
	{u}\ar[r] &  
	*+[F]{v}  \ar@{.>}[rr]&&
	{p,u} \ar@{.>}[r] &
	 *++[o][F]{w,t}     \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] & &&
}

\

\

%%%%%%%%%%%%%%%% f era e 
 \xymatrix@R-=1pt@C-=16pt{
 {(m)}& *++[o][F-]{p} \ar[r] & *+[F]{q} \ar[rd] 
	\ar@{.>}[rr]  &&  
	{r}      \ar@{.>}[rrr] 
                 && &  
	{u,z} \ar[r] & {z} \ar@{.>}[r] & {z} \ar@{.>}[r] &&& {\;\;\:(f)}\\ 
 {(n)}& {p,t}  \ar[r] &  
	{u}\ar[r] &  
	*+[F]{\bigcirc\!\!\!\!\!v\;}  \ar@{.>}[rr]&&
	{p,u} \ar@{.>}[r] &
	  {w,t}     \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] & &&
}


\

\

%%%%%%%%%g
 \xymatrix@R-=1pt@C-=16pt{ 
 {(m)}& {p} \ar[r] & {q} \ar[rd] 
	\ar@{.>}[rr]  &&  
	{r}      \ar@{.>}[rrr] 
                 && &  
	{u,z} \ar[r] & {z} \ar@{.>}[r] &  {z}
 \ar@{.>}[r] &&& {\;\:(g)} \\  
 {(n)}& {p,t}  \ar[r] &  
	{u}\ar[r] &  
	{v}  \ar@{.>}[rr]&&
	*+[F]{p,u} \ar@{.>}[r] &
	 *++[o][F]{w,t}     \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] & &&
}

\

\

%%%%%%%%%%%%%%%%%h
 \xymatrix@R-=1pt@C-=16pt{ 
 {(m)}& {p} \ar[r] & {q} \ar[rd] 
	\ar@{.>}[rr]  &&  
	{r}      \ar@{.>}[rrr] 
                 && &  
	{u,z} \ar[r] & {z} \ar@{.>}[r] &  {z}
 \ar@{.>}[r] &&& {\;\;(h)} \\  
 {(n)}& *+[F]{p,t}  \ar[r] &  
	*+[F]{u}\ar[r] &  
	{v}  \ar@{.>}[rr]&&
	{p,u} \ar@{.>}[r] &
	 *++[o][F]{w,t}     \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] & &&
}

\


\mbox{}\hrule\mbox{}

\

\caption{We provide various representations of a computation, to
outline the distributed states of interest for the examples.}
\end{table}


\

\begin{example} {\em (Invariants.)}  
We consider, as model ${\cal M}$, the computation in
Table~\ref{tabex}. We refer to picture (a), and call $s$ and
$s^{\prime}$ the states outlined by the circle and the rectangle,
respectively. We show that $w\raw t$, $\bar{\mn} (w\raw t)$, and $\mn
\top \raw \mn (w\raw t)$ are invariants of the computation,
while $\mn (w\raw t)$ is not invariant. 

\vspace{-0.4cm}

\begin{description}
\item[${\cal M} \models_T w\raw t$.]  This formula reads: in any
distributed state of the computation, $w\raw t$ holds. 

State $s$ is the only one satisfying $w$. Take $ds = \{s\}$, then $ds
\models w \wedge t$, and thus $ds \models w\raw t$. For any
distributed state $ds' \neq ds$ we have that $ ds'\not\models w$ (even
though $s\in ds'$), and thus $ds' \models w\raw t$.

\item[${\cal M} \models_T \bar{\mn} (w\raw t)$.]  This formula reads:
in any distributed state $w\raw t$ holds in all the states of $n$, or,
in short, $w\raw t$ holds in any state of $n$.

We have to show that for all $ds$, $ds \models \bar{\mn} (w\raw t)$,
that is for all $s_n \in ds\cap S_n$, $\{s_n\} \models w\raw t$.
This, in turn, holds since $\{s\} \models w\wedge t$, and for all $s_n
\neq s$, $\{s_n\} \not\models w$. By the way, this result follows by
{\small \bf Nec} from the previous one.

\item[${\cal M} \models_T \mn \top \; \raw \; \mn (w\raw t)$.]  This
formula reads: in any distributed state of the computation that
contains at least one state of $n$, there is a state of $n$ where
$w\raw t$ holds.
 
Any distributed state $ds$ satisfying the premise $\mn \top$
includes a state in $S_n$, and all states in  $S_n$ satisfy $w\raw
t$. So $ds\models \mn (w\raw t)$.  

\item[${\cal M} \not \models_T \mn (w\raw t)$.]  The formula reads: in
any distributed state of the computation, there is a state of $n$
where $w\raw t$ holds, and it is false in ${\cal M}$.

For ${\cal M} \models_T \mn (w\raw t)$ to be true, we would need that
for all $ds$, $ds \models \mn (w\raw t)$, which is true only if a
state $s_n \in ds\cap S_n$ exists, and satisfies $(w\raw t)$. However,
there are distributed states not including any state $s_n \in S_n$,
e.g. $\{s^{\prime}\}$. In the practice, formulae like $\mm F$ are used
only as subformulae of larger formulae, e.g. as premises and
conclusions of an implication.

\end{description}

\end{example}






\begin{example} \label{ex:temp}
{\em (Temporal operators.)}  
In the example, we refer to pictures (b)--(h) in
Table~\ref{tabex}. The distributed state $ds$ satisfying the premise
is the set of states outlined with a circle, and the distributed state
$ds'$ satisfying the consequence is the set of states outlined with a
rectangle.

\vspace{-0.4cm}

\begin{description}

\item[${\cal M} \models_T \mn u\causes \mm u$.] It is enough to
consider those distributed states that contain the last state of $n$
where $u$ holds. Pictures (b) and (c) show two relevant cases: in the
second case we need to consider a larger distributed state to evaluate
the consequence, just to satisfy the ``follows'' relation.

Picture (c) also shows that DSTL overcomes the problems discussed
at point 3 in the introduction: a distributed state satisfying the
consequence and following $ds$ exists. 


\item[${\cal M}\models \mm p \wedge \mn v \causes \mm z \wedge \mn
t$.]  See picture (d): the distributed state satisfying $ \mm p \wedge
\mn v$ is followed by a distributed state satisfying $\mm z \wedge \mn t$.

\item[${\cal M}\models \mm q\causes \mn v$.]  See picture (e): the
distributed state satisfying the premise includes states which are
irrelevant with respect to property $ \mm q$, for them we only need to
check that the ``follows'' relation is satisfied.  The state
satisfying $z$ belongs both to $ds$ and $ds^{\prime}$.


\item[${\cal M}\models \mm p \wedge \mn v \causesc \mm q$.]  See
picture (f): the state where $q$ holds immediately follows the one
satisfying $p$. Then any state equal or immediately following the one
satisfying $v$ is fine to build the distributed state satisfying the
consequence, and the ``closely'' relation.



\item[${\cal M}\models \mn w \because \mn p \wedge \mn u $.]  Here it
is enough to consider those distributed states that contain the first
state of $n$ where $w$ holds. Then, in the example model, we show two
distributed states that satisfy the consequence: see pictures (g) and
(h).


\item[${\cal M}\models \mn w \because \mn (p \wedge u)$.] See picture
(g).  Note that we need a singleton state satisfying both $p$ and
$q$. Hence, in this case, the distributed state $ds^{\prime}$ in
picture (h) does not satisfy the consequence. 
\end{description}

\end{example}



\begin{table}[t] \label{tabunl}

\mbox{}\hrule\mbox{}

\


%%%%%%%%%%%%%%%%%%%% i

 \xymatrix@R-=1pt@C-=16pt{ 
 {(m)}& {p} \ar[r] & {q,z} \ar[rd] 
	\ar@{.>}[rr]  &&  
	{r,z}      \ar@{.>}[rrr] 
                 && &  
	{u,z} \ar[r] & {z} \ar@{.>}[r] &  {z}
 \ar@{.>}[r] & &&& (i)\\  
 {(n)}& *++[o][F]{p,t}  \ar[r] &  
	*++[o][F]{u,p}\ar[r] &  
	*++[o][F]{v,p}  \ar@{.>}[rr]&&
	*++[o][F]{p,u} \ar@{.>}[r] &
	*+[F]{w,t}     \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] &  &&&
}

\

\


%%%%%%%%%%% l



 \xymatrix@R-=20pt@C-=16pt{ 
 {(m)}& *++[o][F]{p} \ar[r] \ar@{.}[d] \ar@{.}[rd] \ar@{.}[rrd]
 \ar@{.}[rrrrd] & *+[F]{q,z}\ar@{.}[rrrrd] \ar[rd] 
	\ar@{.>}[rr]  &&  
	{r,z}      \ar@{.>}[rrr] 
                 && &  
	{u,z} \ar[r] & {z} \ar@{.>}[r] &  {z}
 \ar@{.>}[r] & &&& (l) \\  
 {(n)}& *++[o][F]{p,t}  \ar[r] &  
	*++[o][F]{u,p}\ar[r] &  
	*++[o][F]{v,p}  \ar@{.>}[rr]&&
	*++[o][F]{p,u} \ar@{.>}[r] &
	*+[F]{w,t}     \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] &  &&&
}


\


\mbox{}\hrule\mbox{}

\

\caption{We provide a pair of representations of a computation, to
outline the distributed states of interest for example~\ref{ex:unl}.}
\end{table}




\begin{example} \label{ex:unl} ($\tunless$ formulae.)   
We consider, as a model, the computation in
Table~\ref{tabunl}. 

\begin{description}

\item[${\cal M}\models \mn p \unless \mn \, t$.]  See picture (i): we
take singleton sets for $ds$ and $ds'$, and outline with a sequence of
circles the sequence of distributed states satisfying the formula
premise, and use a rectangle to outline the distributed state
satisfying the formula consequence.

\item[${\cal M}\models p \unless q \vee t$.] The sequence of
distributed states in picture (i) provides a first demonstration. We
also consider, in picture (l), the distributed states in the sequence
to be pairs of states: each distributed state is made of the two
states related by a dotted line, circles outline the states satisfying
the formula premise, rectangles the  states satisfying the
formula consequence.  For instance, the initial state is the first
distributed state we consider, followed by the set $\{$first state of
$m$, second state of $n\}$, and so on. 

\end{description}

\end{example}

\vspace{0.2cm}


\begin{example} ($ ds^{\prime}\not\supseteq ds $ in the definition of
the semantics of $\tunless$.)
\label{ex:subset}
Assume we did not require condition $ ds^{\prime}\not\supseteq ds $ in
the definition of the semantics of $\tunless$, then the following
computation would have been a model for $\mn p \unless \mn q$, in
discrepancy with the intended meaning for \tunless. We consider the
sequence $ds,\, ds',\, ds'',\, ds''',\ldots$ of distributed states,
where $ds$ contains the first state of component $n$, $ds'$ contains
the first two states of component $n$, $ds''$ contains the first
three, and so on: all these distributed states satisfy $\mn p$.


\vspace{0.2cm}



 \xymatrix@R-=2pt@C-=16pt{ 
 {(m)}& {p} \ar[r]  & {q,z} \ar[rd] 
	\ar@{.>}[rr]  &&  
	{r,z}      \ar@{.>}[rrr] 
                 && &  
	{u,z} \ar[r] & {z} \ar@{.>}[r] &  {z}
 \ar@{.>}[r] & \\  
 {(n)}& {p,t}  \ar[r] 
	\ar@{.}@(dl,dr)[]|{ds}
	\ar@{.}@/_3pc/[r]|{ds'}
	\ar@{.}@/_2pc/[rr]|{ds''} 
	\ar@{.}@/_1pc/[rrrr]|{ds'''}
	&  
	{u}\ar[r] 
	&  
	{v}  \ar@{.>}[rr]
	&&
	{r} \ar@{.>}[r] &
	{t}     \ar@{.>}[rrr]\ar[ru] & & & {t}\ar@{.>}[r] & 
}

\end{example}






\begin{example} ($\tstable$.) The following computation is a model
 for$\stable p$.  


 \xymatrix@R-=1pt@C-=16pt{ {(m)}& {p} \ar[r] & {p} \ar[rd]
 \ar@{.>}[rr] && {r,z} \ar@{.>}[rrr] && & {u,z} \ar[r] & {z}
 \ar@{.>}[r] & {z} \ar@{.>}[r] & \\ {(n)}& {p,t} \ar[r] & {u,p}\ar[r]
 & {v,p} \ar@{.>}[rr]&& {p,u} \ar@{.>}[r] & {p,w,t}
 \ar@{.>}[rrr]\ar[ru] & & & {p,t}\ar@{.>}[r] & }


\vspace{0.2cm}


\noindent
Notice that, unlike in Unity, $p$ is not an invariant of the
computation, even though $\init p$ and $\stable p$ hold. In the next
section, we provide the correct derivation rule (SE) that can be used
in DSTL.
\end{example}



\subsection{Axioms and Rules}
\label{DSTLax}

We present the most useful axioms and rules of the logic.  Among
them, temporal operators introduction, strengthening of premises and
weakening of consequences, transitivity.

\subsubsection{Necessitation.}
First, we observe that the definition for ${\cal M} \models_T F$
entails that a necessitation rule holds (we use $\vdash_{T}$ for the
sake of comprehension).



\begin{center}
{\small
\prooftree
\vdash \ F
\justifies
\vdash_{T} \ F
\using{\bf Nec}
\endprooftree 
}
\end{center}

\vspace{0.2cm}

\subsubsection{Operators introduction and elimination.}

Rules and axioms {\small \bf LcI}, {\small \bf BcI}, {\small \bf LI},
{\small \bf BI}, {\small \bf UI}, {\small \bf InI}, {\small \bf SI}
introduce $\tcausesc$, $\tbecausec$, $\tcauses$, $\tbecause$, $\tunless$, 
$\tinit$, $\tstable$ respectively. Rule {\small \bf SE} eliminates
$\tstable$.



\begin{center}
{\small
{\bf LcI:} \  $F\causesc F$ \hfill
{\bf BcI:} \  $F\becausec F$ \hfill
\prooftree
F\causesc G
\justifies
F\causes G
\using{\bf LI}
\endprooftree  
}
 \hfill{\small
\prooftree
F\becausec G
\justifies
F\because G
\using{\bf BI}
\endprooftree
}
\end{center}


\

\

\begin{center}
{\small
{\bf UI:} \  $F\unless F$
 \hfill
\prooftree
F 
\justifies
\init F 
\using{\bf InI}
\endprooftree
 \hfill 
\prooftree
F 
\justifies
\stable F 
\using{\bf SI}
\endprooftree
 \hfill 
\prooftree
\init \mm F \quad \stable  \mm F 
\justifies
\bar{\mm}F 
\using{\bf SE}
\endprooftree
}
\end{center}








\subsubsection{Transitivity.}

{\small \bf LTR} and {\small \bf BTR} are the rules for $\tcauses$ and
$\tbecause$ transitivity. 


\begin{center}
{\small
\prooftree
F \causes   F^{\prime}  \quad
 F^{\prime}     \!\causes G
\justifies
F \; \causes G
\using{\bf LTR}
\endprooftree
} \quad \quad{\small
\prooftree
F \because   F^{\prime}  \quad
 F^{\prime}     \!\because G
\justifies
F \; \because G
\using{\bf BTR}
\endprooftree
}
\end{center}


\

\noindent
No transitivity rule holds for $\tcausesc$ and $\tbecausec$.  In the
case of $\tunless$, there is a weaker result (a weak form of the rule
called {\em cancellation} in~\cite{chmi88}):


\begin{center}
{\small
\noindent
\prooftree
\mm F \; \unless \; \mm F^{\prime}  \quad
\mm F^{\prime} \; \unless \; \mm G  \quad
\justifies
\mm F \vee \mm F^{\prime} \;  \unless  \;  \mm G
\using{\bf UC}
\endprooftree 
}
\end{center}




\subsubsection{Premises and consequences strengthening and weakening.}

{\small \bf *SW} permits the strengthening of the premise, and the
weakening of the consequences, and {\small \bf *PD} and {\small \bf
*CC} stay for premise disjunction and consequence conjunction,
respectively. Actual rules {\small \bf LSW}, {\small \bf LPD} and
{\small \bf LCC} are obtained by substituting \gop with $\tcauses$.
Similarly, {\small \bf BSW}, {\small \bf BPD}, and {\small \bf BCC}
are obtained by substituting \gop with $\tbecause$; {\small \bf LcSW},
{\small \bf LcPD}, and {\small \bf LcCC} are obtained by substituting
\gop with $\tcausesc$; {\small \bf BcSW}, {\small \bf BcPD}, and {\small
\bf BcCC} are obtained by substituting \gop with $\tbecausec$.



\begin{center}

{\small
\prooftree
G \raw F \quad
F \; \gop \; F^{\prime}  \quad
F^{\prime}  \raw G^{\prime}
\justifies
G \; \gop G^{\prime}
\using{\bf *SW}
\endprooftree 
} \quad \quad 
{\small
\prooftree
F \; \gop \; G  \quad
F^{\prime} \; \gop \; G  
\justifies
F\vee F^{\prime} \; \gop G
\using{\bf *PD}
\endprooftree 
 \quad \quad
\prooftree
G \; \gop \; F  \quad
G \; \gop \; F^{\prime}  
\justifies
G \; \gop F \wedge F^{\prime}
\using{\bf *CC}
\endprooftree 
}
\end{center}




\noindent
In the case of $\tunless$ and $\tinit$: 


\begin{center}
{\small
\noindent
\prooftree
F \; \unless \; F^{\prime}  \quad
F^{\prime}  \raw G
\justifies
F \; \unless \; G
\using{\bf UCW}
\endprooftree 
 \quad \quad
\prooftree
F \; \unless \; F^{\prime}  \quad
 G \; \unless \; G^{\prime}  \quad
\justifies
F \vee G \unless F^{\prime} \vee
G^{\prime}
\using{\bf UD}
\endprooftree 
 \quad \quad
\prooftree
\init F  \quad F \raw G
\justifies
\init G 
\using{\bf IW}
\endprooftree 
}
\end{center}


\subsubsection{Notification.}  
Some future remote assertions can be made on the bases of a message
received.

\begin{center}
{\small
\noindent
\prooftree
F \because G \quad G \causes \mm G^{\prime} \quad \stable \mm G^{\prime}
\justifies
F \wedge \mm \top \causes \mm G^{\prime}
\using{\bf Notif}
\endprooftree 
}
\end{center}

\

\noindent
Explicit reference to the name $\mm$ of the component where the remote
effect $G^{\prime}$ takes place, and the extra premise $\mm \top$ are
needed to guarantee that the state satisfying the consequence follows
the state satisfying the premise, even in the absence of a
communication towards $\mm$.

\

\noindent
To help the intuition, we consider an instance of the rule: 

\begin{center}
{\small
\noindent
\prooftree
\mn p \because \mm q \quad \mm q \causes \mm r \quad \stable \mm r
\justifies
\mn p \wedge \mm \top \causes \mm r
\endprooftree 
}
\end{center}

\

\noindent
condition $p$ can be established in $\mn$ only if previously $q$ has
held in $\mm$. The second and the third premises guarantee that if $q$
holds somewhere in $\mm$, then eventually $r$ will hold, and it will
continue holding forever. Thus, for any $ds$ satisfying $\mn p \wedge
\mm \top$ we can find a state $s_m$ of $S_{m}$, such that $\{s_m\}\geq
ds$ and $\{s_m\}\models \mm r$. Conversely, in the absence of
communications from $\mn$ to $\mm$, if we take a state $s_n$ of
$S_{n}$ such that $\{s_n\}\models \mn p$, we cannot find any
distributed state following $\{s_n\}$ and including a state of $
S_{m}$, as needed to satisfy $\mm r$.


\subsubsection{Confluence.} 
The converse of DSL axiom {\small \bf D2} holds, under appropriate
stability conditions:



\begin{center}
{\small
\noindent
\prooftree
\stable  \mm F \quad \stable  \mm F^{\prime} 
\justifies
\mm F\wedge \mm F^{\prime}  \ \raw \ \mm (F\wedge F^{\prime})
\using{\bf Conf}
\endprooftree 
}
\end{center}




\subsubsection{Properties of the initial  state.} The following rules are a
consequence of the fact that the initial distributed state $ds^0$
contains exactly one state for each component.

\

{\small
{\bf I1:} \  $\init \mm \top$ \quad \quad \quad  \quad \quad  
\prooftree
\init \mm F
\justifies
\init \bar{\mm} F 
\using{\bf I2}
\endprooftree \quad \quad \quad  \quad \quad  
\prooftree
\init \bar{\mm} F 
\justifies
\init \mm F
\using{\bf I3}
\endprooftree 
}

\vspace{0.3cm}

\begin{example} (SE)
The following computation satisfies $\init \mm p$  and $\stable \mm p$. 


\vspace{0.2cm}

\xymatrix@R-=1pt@C-=16pt{ 
 {(m)}& {p} \ar[r] & {p} \ar[rd] 
	\ar@{.>}[rr]  &&  
	{p,r,z}      \ar@{.>}[rrr] 
                 && &  
	{p,u,z} \ar[r] & {p,z} \ar@{.>}[r] &  {p,z}
 \ar@{.>}[r] & \\  
 {(n)}& {p,t}  \ar[r] &  
	{u}\ar[r] &  
	{v,p}  \ar@{.>}[rr]&&
	{u} \ar@{.>}[r] &
	{w,t}     \ar@{.>}[rrr]\ar[ru] & & & {p,t}\ar@{.>}[r] & 
}

\vspace{0.3cm}

\noindent 
 Hence, applying rule SE, we obtain that the
computation satisfies $\bar{\mm}p$, i.e. that $p$ is invariantly true
in component $\mm$.

\end{example}



\noindent
It is also interesting to discuss why the cancellation rule 

\begin{center}
{\small
\noindent
\prooftree
F \; \unless \; F^{\prime}  \quad
F^{\prime} \; \unless \; G  \quad
\justifies
F \vee F^{\prime} \;  \unless  \;  G
\endprooftree 
}
\end{center}


\noindent
does not hold in general. We consider, as rule premises, $\mm
p\unless \mm p \wedge \mn q$ and $\mm p \wedge \mn q \unless \mm r
\wedge \mn s$. The following computation is a model of the premises,
but not of the consequence $\mm p \vee (\mm p \wedge \mn q) \unless
\mm r \wedge \mn s$. 


\xymatrix@R-=1pt@C-=16pt{ 
 {(m)}& {p} \ar@{.>}[rr] && {p} \ar[rd] 
	\ar[r]  &
	{r}      \ar@{.>}[rrr] 
                 && &  
	{u,z} \ar[r] & {z} \ar@{.>}[r] &  {z}
 \ar@{.>}[r] & \\  
 {(n)}& {p,t}  \ar[r] &  
	{u}\ar@{.>}[rr] &  &
	{q}  \ar[r]&
	{s} \ar@{.>}[r] &
	{w,t}     \ar@{.>}[rrr]\ar[ru] & & & {p,t}\ar@{.>}[r] & 
}



\

\

\noindent
{\bf Theorems.}  We introduce two rules we need in
the case study of Section~\ref{example2}. They are derived by the
rules above, as shown in the appendix.

\begin{center}
{\small
\noindent
\prooftree
F  \causes  G\vee G^{\prime}  \quad
G \causes F^{\prime} 
\justifies
F \causes F^{\prime} \vee G^{\prime} 
\using{\mbox{\small Cor1}}
\endprooftree 
 \quad \quad \quad
\prooftree
F  \causes  G\wedge G^{\prime}  \quad
G \causes F^{\prime} 
\justifies
F \causes F^{\prime} \wedge G^{\prime} 
\using{\mbox{\small Cor2}}
\endprooftree 
}
\end{center}

\

\

\noindent
{\bf Correctness and completeness.}  The soundness of the DSTL proof
system can be immediately proved applying Def.~\ref{DSTLsemantics}. In
the appendix we provide the proof of the most complex rules, namely
{\small \bf Notif} and {\small \bf Conf}.

Unfortunately, the proof system is not complete. Let us consider a
system satisfying $\bar{\mm}_i p$, for all $i$. The system also
satisfies $p$, as a consequence of the property $V(ds)=
\bigcap_{s\in ds} V(\{s\})$, but we cannot find a general rule to
derive it. Indeed, the rule

\vspace{0.2cm}

\begin{center}
{\small
\prooftree
\bar{\mm}_1 F \quad \bar{\mm}_2 F  \quad \ldots  \quad \bar{\mm}_k F 
\justifies
F
\endprooftree 
}
\end{center}


\vspace{0.2cm}

\noindent 
is not correct. It holds for $F=p$, or $F=p\wedge q$, but not, for
instance, for $F=p\vee q$. In fact, consider a very simple system
composed of a unique component $m$, with states $s_0,s_1, s_2\ldots$,
and $p\in V(s_0)$, $q\in V(s_1)$, $q\in V(s_2)$, $\ldots$. All
distributed states satisfy $\bar{\mm} \, (p\vee q)$, while the
distributed states including $s_0$ do not satisfy $p\vee q$. Take
$ds=\{s_0,s_1\}$, we have that $ds \models p\vee q$ iff $ds \models p$
or $ds \models q$, iff $p\in V(ds)$ or $q\in V(ds)$, iff $p\in
V(s_0)\cap V(s_1)$ or $q\in V(s_0)\cap V(s_1)$. Hence, since
$V(s_0)\cap V(s_1)=\emptyset$, we have that $ds \not \models p\vee q$.

Thus, a complete proof system, if any, would likely be unmanageable,
and we do not pursue the issue further. On the other side, the
consequence of relaxing the constraint on the valuation function,
would be as unpractical as explicitly specifying the truth value of
all predicated on all distributed states.



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{An  Example: Private Keys}
\label{example}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



Consider the system $\{b,t,u\}$, where $b$ is a component that
broadcasts the encrypted version of a message to all the other
components in the system, i.e. $t$ (trusted) and $u$ (untrusted). We
assume that these components try to decrypt the message. We represent
with predicate $p$ the fact that the message is readable, and with
predicate $dep$ the fact that a decryption has been
attempted. However, the decryption yields $p$ if and only if the key
is held. Predicate $key$ represents the property of holding the key.


\subsection{Reasoning on distributed states: DSL} 
\label{ex1}

The properties of the distributed states of the system are described
by the following DSL formulae:

\vspace{-0.6cm}

\begin{eqnarray}
&&(\sim \mbb \top) \raw ((key \wedge dep) \lraw p) \label{k1}\\
&& \bar{\mtt} \, key\label{k2}\\
&& \bar{\muu} \sim key\label{k3}
\end{eqnarray}

\noindent
Formula~(\ref{k1}) tells that in all components, with the exception of
$b$, $p$ and $dep$ are equivalent only if the key is held. Indeed, if
(\ref{k1}) holds, as required, in all $ds\in DS$, it holds in particular
in all $ds$ which are singleton sets. So, it holds for all $\{s_t\}$
and $\{s_u\}$. Since in these states the premise of (\ref{k1}) is
satisfied, so it is the conclusion, i.e. in all states of $t$ and $u$:
$(key \wedge dep) \lraw p$. We derive the property for $t$:


\

\begin{center}

{\small
\prooftree
\prooftree
(\sim \mbb \top) \raw ((key \wedge dep) \lraw p)
\justifies
\bar{\mtt} (\sim \mbb \top) \raw \bar{\mtt} ((key \wedge dep) \lraw p)
\using{\mbox{\small Nec, K}}
\endprooftree
\quad
\prooftree
\bar{\mtt} \, \bar{\mbb} \bot
\justifies
\bar{\mtt} (\sim \mbb \top)
\endprooftree
\justifies
\bar{\mtt} ((key \wedge dep) \lraw p)
\using{\mbox{\small MP}}
\endprooftree
}

\end{center}


\



\noindent
Component $t$ holds the key (\ref{k2}), while component $u$ does not
(\ref{k3}).  We derive that $t$ is able to correctly decrypt the
message.  We pick one of the implications, i.e. $(key \wedge dep) \raw
p$ and prove that $\bar{\mtt} \, (dep \raw p)$ (the top leftmost
formula is a tautology of the propositional calculus):

\

\begin{center}

{\small
\prooftree
\prooftree
\prooftree
((key \wedge dep) \raw p ) \raw (key\raw(dep\raw p))
\quad \quad \bar{\mtt} ((key \wedge dep) \lraw p)
\justifies
 \bar{\mtt} \, (key\raw(dep\raw p))
\using{\mbox{\small Nec, K, MP}}
\endprooftree
\justifies 
\bar{\mtt} \, key\raw \bar{\mtt} \,(dep\raw p)
\using{\mbox{\small K}}
\endprooftree
\quad
\bar{\mtt} \, key
\justifies 
 \bar{\mtt}\, (dep\raw p)
\using{\mbox{\small MP}}
\endprooftree
}

\end{center}


\


\noindent
We now consider component $u$ and prove that $\bar{\muu} \sim p$
holds, i.e. that the untrusted component is not able to read the
message. We consider the implication $p\raw (key \wedge dep)$ (the top
leftmost formula is a tautology of the propositional calculus):

\

\begin{center}

{\small
\prooftree
\prooftree
(p\raw (key \wedge dep) ) \raw (\sim key \raw \sim p)
\quad\quad \bar{\muu}\, ((key \wedge dep) \lraw p)
\justifies
 \bar{\muu}\, (\sim key \raw \sim p)
\using{\mbox{\small Nec, K, MP}}
\endprooftree
\quad \bar{\muu}\, \sim key
\justifies
 \bar{\muu}\,  \sim p
\using{\mbox{\small K,MP}}
\endprooftree
}

\end{center}


\subsection{Reasoning on distributed computations: DSTL}


 We now add some constraints on the temporal behaviour of the private
keys system: as soon as the message is readable in $b$, $b$ broadcasts
its encrypted version (\ref{L1}); $t$ and $u$ try to decrypt the
message (\ref{L2}, \ref{L3}). 
\begin{eqnarray}
&&\mbb \,p  \; \causes  \; \mtt \, ep \wedge \muu \,ep  \mbox{\hspace{6cm}}
		 \label{L1}\\
&&  \mtt\, ep  \; \causes  \; \mtt \,dep \label{L2}\\
&& \muu \, ep  \; \causes \; \muu \, dep \label{L3}
\end{eqnarray}


\noindent
To prove that $u$ will not correctly decrypt the message, we need to
prove that $ \bar{\muu} \sim p$. This is immediately obtained by
applying {\small \bf Nec} to the corresponding DSL formula derived in
Section~\ref{ex1}. We prove that $\mbb \, p \: \causes \: \mtt \,
p$. We exploit the conclusion of Section~\ref{ex1}: $\bar{\mtt} \,
(dep\raw p)$




\

{\small
\prooftree
\prooftree
\prooftree
\mbb \,p  \; \causes  \; \mtt \, ep \wedge \muu \,ep   \quad (\mtt \, ep \wedge \muu\,
ep) \raw  \mtt\,  ep
\justifies
\mbb\, p  \: \causes \: \mtt \, ep
\using{\mbox{\small LSW}}
\endprooftree 
  \mtt\, ep  \; \causes  \; \mtt \,dep
\justifies
\mbb  \, p  \: \causes \: \mtt  \,dep 
\using{\mbox{\small LTR}}
\endprooftree 
\quad\quad\quad \prooftree
\bar{\mtt} \,  (dep\raw p)
\justifies
\mtt  \,dep\raw \mtt \, p
\using{\mbox{\small D3}}
\endprooftree 
\justifies
\mbb  \,  p \: \causes \: \mtt  \, p
\using{\mbox{\small LSW}}
\endprooftree 
}

\



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{An  Example: Leader Election}
\label{example2}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

The leader election problem is a typical example of distributed
consensus. It is well known that in an asynchronous setting, no
algorithm can guarantee that a distributed consensus is reached (see,
for instance~\cite{CatSynch}). The solution we discuss here leads to
the election of a leader, or to the agreement that no leader has been
chosen, in this case a new election round can take place.

Initially all the $k$ participants are eligible. They toss a coin:
those who get head are no longer eligible and acknowledge the other
participants; those who get tail toss the coin again. The election
round ends when either only one participant is still eligible and
becomes the leader, or nobody is eligible.


\

\noindent
Predicate $e_i$ says that participant $i$ is still eligible: initially
all participants agree that they are all eligible; each participant
falsify his $e_i$ when acknowledged that participant $i$ got a head.

In the following we list the local properties satisfied by each
participant and derive the global property of the proposed solution:
eventually  all participants agree that either nobody is eligible,
i.e. $\sim e_i$ holds for all $i$ and for all participants, or only
one participant is still eligible, i.e. there exists a $j$ such that
for all participants $e_j$ holds while $e_k$ is false for all $k\neq
j$. Formally:


\vspace{-0.6cm}

\begin{eqnarray*}
\bigwedge_i \mii \top & \causes & \quad 
\bigwedge_i  \mii   \bigwedge_j \sim e_j 
\quad \vee \quad
\bigvee_j \bigwedge_i  \mii  ( e_j \wedge  \bigwedge_{k\neq j} \sim e_k)
\end{eqnarray*}


\noindent
In the case of two participants:

\vspace{-0.6cm}

\begin{eqnarray*}
\mI \top \wedge \mII \top & \causes & 
\mI (\sim e_1 \wedge \sim e_2)  \wedge
 \mII (\sim e_1 \wedge \sim e_2) \quad \quad\quad \mbox{(no leader elected)}\\
&&\vee \quad   \mI ( e_1 \wedge  \sim e_2)  \wedge
 \mII ( e_1 \wedge  \sim e_2) \quad \quad \quad \mbox{ ($e_1$ elected)}\\
&&\vee \quad   \mI (e_2 \wedge  \sim e_1 )  \wedge
 \mII (e_2 \wedge  \sim e_1 )\quad \quad \quad \mbox{ ($e_2$ elected)}
\end{eqnarray*}


\noindent
The local properties follow.

\begin{enumerate}

\item Fairness of the toss up: nobody can spin the coin infinite times
and nether get a head. So, either a participant eventually stops
spinning the coin or he gets a head.  For all $i$:

\vspace{-0.6cm}

\begin{eqnarray*}
&& \mii \top \causes \mii (stop \vee h)
\end{eqnarray*}

\item Participant $i$ stops if and only if the other participants
are no longer eligible:


\vspace{-0.6cm}  

\begin{eqnarray*}
&& \bar{\mm}_{\bf \sf i} (stop \lraw \bigwedge_{j\neq i} \sim e_j )
\end{eqnarray*}


\item When  participant $i$ gets a head, he sends an ack to all 
participants, who declare $i$ non eligible.

\vspace{-0.6cm}

\begin{eqnarray*}
&& \mii h \causes \bigwedge_j \mij \sim e_i
\end{eqnarray*}

\item A participant can be  declared non eligible only if he got a
head:

\vspace{-0.6cm}

\begin{eqnarray*}
&& \mii  \sim e_j \because \mij h
\end{eqnarray*}

\item Initially all participants are eligible. 

\vspace{-0.6cm}

\begin{eqnarray*}
&& \init \bigwedge_i \mii  (\bigwedge_j e_j \wedge \sim h)
\end{eqnarray*}

\item Non eligibility is stable:

\vspace{-0.6cm}

\begin{eqnarray*}
&& \stable \mii \sim e_j 
\end{eqnarray*}

\end{enumerate}

\noindent
We prove that the global property holds in the case of two
participants.  The proofs for the other cases are similar. 
In the first step of the proof, we exploit properties 1 and 2:


\

\begin{center}
{\small
\noindent
\prooftree
%
\prooftree
\mI \top \causes \mI (stop \vee h)
\justifies
\mI \top \causes \mI stop \vee \mI h
\using {\mbox{\small D7}}
\endprooftree 
%
\  \prooftree
\bar{\mm}_{\bf \sf 1}  (stop \lraw \sim e_2)      
\justifies
\mI stop \ \lraw \ \mI \sim e_2
\using {\mbox{\small D3}}
\endprooftree 
%
\justifies \mI \top \causes \mI h \vee \mI \sim e_2
\using {\mbox{\small LSW}}
\endprooftree  
}
\end{center}

\

\noindent
The same holds for $\mII$. We apply {\small \bf LSW} and {\small \bf
LCC} and obtain:

\vspace{-0.6cm}

\begin{eqnarray}
\mI \top \wedge \mII \top & \causes & \quad \mI h  \wedge \mII h \label{hh} \\
&&  \vee  \quad  \mI h  \wedge  \mII \sim e_1 \label{he} \\
&&  \vee  \quad  \mI \sim e_2 \wedge  \mII h \label{eh} \\
&&  \vee  \quad  \mI \sim e_2 \wedge \mII \sim e_1 \label{ee} 
\end{eqnarray}

\noindent
In the remaining part of the section we prove that: 

\vspace{-0.6cm}

\begin{eqnarray*}
(\ref{hh})  & \causes & 
	\mI (\sim e_1  \wedge \sim e_2 ) \wedge   
	\mII (\sim e_1 \wedge \sim e_2) 
	\quad \quad \quad \quad \mbox{(no leader elected)} \\
(\ref{he}) & \causes & 
	\mI (\sim e_1 \wedge e_2) \wedge \mII (\sim e_1 \wedge e_2) \\
	&&  \vee \ \mI (\sim e_1 \wedge \sim e_2) 
	\wedge \mII (\sim e_1 \wedge \sim e_2)
	\quad \quad \quad \mbox{($e_2$ elected or no leader)} \\
(\ref{eh}) & \causes &
	\mI (e_1 \wedge \sim e_2) \wedge \mII (e_1 \wedge \sim e_2) \\
	&&  \vee \ \mI (\sim e_1 \wedge \sim e_2) 
	\wedge \mII (\sim e_1 \wedge \sim e_2) 
	\quad \quad \quad \mbox{($e_1$ elected or no leader)} \\
(\ref{ee}) & \causes & 
	\mI (\sim e_1 \wedge \sim e_2)
 	\wedge \mII (\sim e_1\wedge \sim e_2)
	\quad \quad \quad \quad  \mbox{(no leader elected)} 
\end{eqnarray*}


\noindent
So, we can apply {\small \bf Cor1} and conclude.  


\

\noindent
{\bf Proof of} $(\ref{hh}) \causes$ no leader elected 

\

\noindent 
We exploit hypothesis 3:  

\vspace{-0.6cm}

\begin{eqnarray*}
\mI h  \wedge \mII h & \causes & 
\mI \sim e_1  \wedge  \mII \sim e_1 \wedge 
\mI \sim e_2  \wedge  \mII \sim e_2 
\end{eqnarray*}

\noindent
We apply {\small \bf Conf}:

\begin{center}
{\small
\noindent
\prooftree
   \stable \mI \sim e_1     \quad     \stable \mI \sim e_2
   \justifies 
   \mI \sim e_1 \wedge \mI \sim e_2 \ \raw \  \mI (\sim e_1 \wedge \sim e_2) 
\endprooftree  
}
\end{center}

\noindent
A similar implication holds for $\mII$, hence:

\vspace{-0.6cm}

\begin{eqnarray*}
\mI h  \wedge \mII h & \causes & 
\mI (\sim e_1  \wedge \sim e_2)   \wedge  
\mII (\sim e_1 \wedge  \sim e_2)
\end{eqnarray*}

\

\noindent
{\bf Proof of} $(\ref{he}) \causes e_2$ elected or no leader elected
(the case for (\ref{eh}) is symmetric).

\

\noindent
We exploit again hypothesis 3 and obtain, using
{\small \bf Cor2}, that:

\vspace{-0.6cm}

\begin{eqnarray*}
\mI h  \wedge  \mII \sim e_1  & \causes & \mI \sim e_1  \wedge  \mII \sim e_1 
\end{eqnarray*}

\noindent
Now, since we don't know anything on the truth of $e_2$, we need to
consider all the possibilities:

\vspace{-0.6cm}

\begin{eqnarray}
\mI \sim e_1  \wedge  \mII \sim e_1 &\LRaw & 
	\quad \mI (\sim e_1 \wedge e_2) \wedge \mII (\sim e_1 \wedge e_2) 
		\label{cc1}\\
&& \vee  \mI (\sim e_1 \wedge \sim e_2) \wedge \mII (\sim e_1 \wedge e_2)
	\label{cc2}\\
&& \vee  \mI (\sim e_1 \wedge e_2) \wedge \mII (\sim e_1 \wedge \sim e_2)
	\label{cc3}\\
&&\vee  \mI (\sim e_1 \wedge \sim e_2) \wedge \mII (\sim e_1 \wedge \sim e_2)
	\label{cc4}
\end{eqnarray}


\noindent
In case~(\ref{cc1}) an agreement is reached that $e_2$ is the
leader. In case~(\ref{cc4}) the participants agree that no leader has
been elected. The other two cases are symmetric: 
we consider case~(\ref{cc2}) and show that it leads to a state where
no leader has been elected. We first show that a state
is reached where participant $2$ agrees that he cannot be the leader: 


\begin{center}
{\small
\noindent
	\prooftree
		\prooftree
		\mI \sim e_2 \because \mII h
		\justifies 
		\mI (\sim e_1 \wedge \sim e_2) \because \mII h
		\using{\mbox{\small BSW}}
		\endprooftree
		  \mII h \causes  \mII \sim e_2 
		\quad \quad \stable  \mII \sim e_2 \quad \quad \mbox{ }
	\justifies 
\prooftree
	\mI (\sim e_1 \wedge \sim e_2) \wedge \mII  \top \causes \mII \sim e_2 
\justifies 
 \mI (\sim e_1 \wedge \sim e_2) \wedge \mII (\sim e_1 \wedge e_2) 
\causes \mII \sim e_2 
	\using{\mbox{\small LSW}}
\endprooftree  
	\using{\mbox{\small Notif}}
	\endprooftree
}
\end{center}

\

\noindent
where the last step ({\small LSW}) exploits the following implication:

\begin{center}
{\small
\noindent
	\prooftree
	\sim e_1 \wedge e_2 \raw \top
	\justifies 
	 \mII (\sim e_1 \wedge e_2) 
	\raw 
	 \mII  \top
	\using{\mbox{\small Nec,D3}}
	\endprooftree
}
\end{center}


\noindent
We carry on some calculation:

\begin{center}
{\small
\noindent
\prooftree
  \prooftree
	\mI (\sim e_1 \wedge \sim e_2) \wedge \mII (\sim e_1 \wedge e_2) 
   \causes \mII \sim e_2  
   \justifies 
   \mI (\sim e_1 \wedge \sim e_2) \wedge \mII (\sim e_1 \wedge e_2) 
   \causes \mI (\sim e_1 \wedge \sim e_2) \wedge \mII (\sim e_1 \wedge e_2) 
              \wedge \mII \sim e_2
\using{\small LCC ({\tiny F\causes F})}
\endprooftree  
\justifies 
   \mI (\sim e_1 \wedge \sim e_2) \wedge \mII (\sim e_1 \wedge e_2) 
   \causes \mI (\sim e_1 \wedge \sim e_2) \wedge \mII \sim e_1 
  \wedge \mII \sim e_2
\using{\small D2, LSW (twice)}
\endprooftree  
}
\end{center}

\

\noindent
We now apply {\small \bf Conf} and conclude:

\

$\mI (\sim e_1 \wedge \sim e_2) \wedge \mII (\sim e_1 \wedge e_2) 
\causes \mI (\sim e_1 \wedge \sim e_2) \wedge \mII (\sim e_1 \wedge \sim e_2) 
$




\

\noindent
{\bf Proof of} $(\ref{ee}) \causes$ no leader elected


\

\noindent
We apply the proof schema above ({\small \bf
Notif} and then {\small \bf Conf}) twice and conclude. 



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Discussion and Related Work}
\label{discussion}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


{\bf The semantic domain of DSL.} The choice of $2^S$ as a semantic
domain of the distributed state logic formulae, and the
non--equivalence between $\mm\, (F \wedge F)$ and $ \mm \, F \wedge
\mm\, F'$ are useful to specify that a given condition can have
different future effects, without constraining them to occur in the
same state. Similarly, we can express complex preconditions in a
temporal formula. For instance, assume we want to specify and reason
on the delivery of credit cards to customers. The bank, for security
reasons, sends the card and the code separately.  Once the customer
has got both of them, he is allowed to withdraw money from an ATM
machine:
\begin{eqnarray}
&& \bank\, new\_card \; \causes \; \user\, receive\_card \wedge 
	\user \,receive\_code 
	\label{bank1}\\
 &&  \user\,
	can\_withdraw \; \because   \; \user \, receive\_card \wedge 
	\user\, receive\_code
\label{bank2}
\end{eqnarray}



\noindent
The equivalence between $\mm\, (F \wedge F)$ and $ \mm\, F \wedge \mm\, F'$
would have required the following specification, somewhat less intuitive: 
\begin{eqnarray}
&& \bank\, new\_card \;\causes \; \user \,receive\_card
	\label{banku1}\\
&& \bank\, new\_card \;\causes \; \user \,receive\_code 
	\label{banku2}\\
&& \user\, can\_withdraw  \; \because   \; \user \, receive\_card 
	\label{banku3}\\
&& \user\, can\_withdraw  \; \because   \; \user\, receive\_code
	\quad	\quad \mbox{ }\quad\quad \mbox{ }\quad\quad\quad \mbox{ }
	\label{banku4}
\end{eqnarray}

\noindent
since~(\ref{bank1}),~(\ref{bank2}) would be too restrictive, asking
for card and code to be received at the same time.


Last, but not least, with an eye to a $1^{st}$ order extension, a
formula like~(\ref{bank1}) makes it easier to bind variables in $card$
and $code$ than with the unrelated
formulae~(\ref{banku1}),~(\ref{banku2}).

\

\noindent
{\bf Classical Logic.} Another point of discussion is why we
need a modality ($\mm$) rather than a distinguished propositional
symbol $here_m$, to replace systematically each sub--formula $\mm\, F$
with $here_m \wedge F$. One motivation is that we do not want the
equivalence between $\mm\, (F \wedge F'$) and $ \mm\, F \wedge \mm\,
F'$, as discussed previously. On the contrary, the two translations
$here_m \wedge F\wedge F'$ and $here_m \wedge F\wedge here_m \wedge
F'$ would be equivalent. 

More importantly, $(\mm F \wedge \mn F') \causes \moo G$ would be
translated in a formula with a false premise, namely $(here_m \wedge F
\wedge here_n \wedge F') \causes (here_o \wedge G)$. 

\

\noindent
{\bf Hybrid Logic.}  Hybrid logic allows the specifier to directly
refer to specific points (states) in the model, through the use of
{\em nominals}~\cite{tesiAreces}.  A nominal $i$ is an atom which is
true at exactly one point in any model.  The operator $@_i$ permits to
jump to the point named by nominal $i$.  We might consider defining an
hybrid signature including distinguished sets of state variables, one
for each component, and translate $\mm\, F$ in $\exists x.\; @_{x}F$,
where $x$ is a state variable in the appropriate set. Likely, the
resulting setting would be more complex than that offered by DSTL.

\

\noindent
{\bf Metric and Layered Temporal Logic.}  Some similarities can be
found between our location operator and the $MLTL$ operators defined
in~\cite{tesiAmontanari}, that make it possible to compose formulae
associated with different time granularities and to switch from one
granularity to another.  Time instants are organized in temporal
domains, and the set of temporal domains is totally ordered with
respect to the coarseness of the domain elements. To look for an
embedding of DSTL, we can consider three domains: {\em system}, with a
unique element; {\em components}, whose elements are the components
$m_1, \ldots, m_k$; {\em states}, the domain of the states. Then the
formulae are translated using an appropriate combination of $MLTL$
operators. For instance, the translation of $\mm\, F$ should be
$\diamond \Delta_m^{components} \diamond \exists \alpha
\Delta_\alpha^{states} F$. Since the full expressive power of $MLTL$
is likely not needed, the simpler framework of DSTL is of pragmatical
interest.


\



\noindent
{\bf  Other logics for distributed systems.}  Various extensions
of temporal logic have been defined in the literature to deal with
distributed
systems. 

 In TTL~\cite{masini92}, for each local state of the system, a {\em
 visibility} function specifies which remote information is
 accessible. The visibility function is defined on the basis of a
 relation among states which is {\em symmetric} in the case of states
 belonging to distinguished components.

 A trace based extension of linear time temporal logic, called {\em
 TrPTL}, has been defined in ~\cite{Thiaga94} (see also
 ~\cite{Thiaga98DVL}). The logic has been designed to be interpreted
 over infinite traces, i.e., labelled partial orders of actions, which
 respect some dependence relations associated to the alphabet of
 actions.  

 In~\cite{lprm95}, a temporal logic, StepTL, is defined and interpreted
 over multistep transition systems. These are a well known extension of
 transition systems, permitting to describe as concurrent the steps of
 computation that can actually be executed in parallel.  A multistep
 transition system thus contains transitions of the form $s\,A\,s'$,
 where $A$ is a set of actions, instead of a single one.

 Three distinguished logics are presented in~\cite{Rama96} to describe
 systems composed of sets of communicating {\em agents}. The logics
 differentiate on the amount of information each agent can have on the
 other agents running on the system, but share a common setting: agents
 communicate via common actions.  The models for these logics are runs
 of networks of synchronizing automata.  The logics {\bf D}$_0$ and
 {\bf D}$_1$ presented in~\cite{EhrichDalLibro} are based on a similar
 approach. 

In all these proposals, components communicate via some form of
synchronization, and logic formulae are interpreted on models shaping:

\vspace{0.2cm}

\hspace{1cm}\xymatrix@R-=9pt{
{(m)}&\ar@{.>}[rr]&& {a} \ar@{.>}[r] & {b} \ar@{.>}[rr] && {c} \ar@{.>}[r] &\\
{(n)}&\ar@{.>}[r]& {d} \ar@{.>}[rr] && {e} \ar@{<->}[u] \ar@{.>}[r] &
{f} \ar@{.>}[rr] &&
}

\

\noindent
Therefore, in any logic defined over these models, it is not possible
to express the asymmetric nature of causality we are interested in when
modelling the behaviour of agents communicating asynchronously by
message passing. Indeed, in the previous model we can both assert that
$a \causes f$ and that $d \causes c$.



A logic closer to DSTL is proposed in~\cite{LodRamThi92Corto}, where a
        branching time temporal logic for asynchronously communicating
        sequential agents (ACSAs) is defined. ACSAs communicate
        asynchronously via message passing. The logic contains
        temporal modalities indexed with a local point of view of one
        agent and allows an agent ``i'' to refer to local properties
        of another agent ``j'' according to the latest message
        received: an agent can gain information about another agent by
        receiving messages but not by sending them.  We allow agents
        to make remote future assertions: therefore it is easier to
        express global liveness properties.





\

\noindent
{\bf  Knowledge Logic.} 
A logic to reason on asynchronous message passing systems is proposed
in~\cite{fhmv95}. The language used, ${\cal L}^U _n$, is obtained by
extending their language of knowledge with the modal operators $U$ and
$\nex$. Formulae in ${\cal L}^U _n$ permit to express how the $n$ {\em
agents} in a system gain knowledge over time.
A set of characteristic formulae valid in the logic are presented, but
a sound and complete axiom system is not defined.
The authors focus their attention on systems based un-reliable
communications, while only state that properties of reliable
communications can be expressed. 
A major difference with our work relies on the models used to
interpret ${\cal L}^U _n$ formulae. Even if the knowledge of the
agents is limited to their current local histories, i.e. sequences of
messages sent or received and of internal actions, interpretation
structures are based on global time and state.
                                     



\

\noindent
{\bf Partial Order Temporal Logics.}
Partial Order Temporal Logics (POTL)~\cite{PiWo} permits to deal with
the causal relationships between the events of a set of processes
executing concurrently. The Interleaving Set Temporal Logic
(ISTL)~\cite{LogKatz} extends POTL with features form linear temporal
logic and branching temporal logic. The Kripke structures for both
logics are very different from the one defined in this paper.

We are addressing a specific class of systems that we consider very
relevant nowadays, that is distributed systems with asynchronous
message passing. These systems have a few notable characteristics:
there is no global state, and interactions among components occur only
via messages. As a consequence, a specification is essentially devoted
to describing the causal relationships among the components. We think
that these characteristics are so important that the designer
working on a specification will greatly benefit if they are naturally
embedded in the basic model he is using. Hence, the
investigation in Kripke's structures presented in this paper. 




\

\noindent
{\bf Logics for Mobile Systems.} 
 Often mobile systems are specified using a process calculus with
 primitives for mobility, and some logics have been defined, tailored
 for these calculi. This is the case, for instance, of the Ambient
 Logic~\cite{CG00:logic-for-MA}, studied for the Ambient
 Calculus~\cite{CG00:mobile-ambients}, the logic for Klaim~\cite{loretiTOCL},
 and the Spatial Logic for Concurrency~\cite{CardCair1e2}, whose
 underlying computational model is the asynchronous
 $\pi$--calculus. These logics include modalities for describing the
 evolution over time and the location of the system processes. They
 are inspired by the Hennessy--Milner logic: they are conceived
 for model checking rather than for specifying and reasoning on the system
 properties.

In particular, the Spatial Logic for Concurrency can express
properties of freshness, secrecy, structure, and behavior of
concurrent systems.  Spatial operations correspond to composition,
local name restriction, and a primitive fresh name quantifier.  The
logical treatment of the notion of freshness can prove useful in
extending DSTL to reason on the dynamic creation of components.

A linear--time logic for specifying mobile systems is
MTLA~\cite{merz03}, which extends Lamport's Temporal Logic of Actions
with spatial modalities to deal with mobile systems. The main
difference with DSTL is that a synchronous computational model is
assumed.


\

\noindent
{\bf Oikos--{\em adtl}.}  The work reported here stems from our
experience with Oikos--{\em adtl}, a specification language for
distributed systems based on asynchronous communications, designed to
support the composition of specifications~\cite{coord99c}.  \oikosadtl
is intended to give designers a language to express the properties of
interest in a natural way, and it is associated with a refinement
method which supports the gradual introduction of details, as design
proceeds.  It has been used to specify software architectures and
patterns~\cite{isawCorto} and to analyse security issues in
mobile systems~\cite{wits00Corto,adhoc,denver}. It is supported by a
proof assistant, Mark~\cite{mark}, that deploys a number of proof
strategies that partially automate property verification.

Coming back to our motivating example in the introduction, in
Oikos--{\em adtl} it is possible to weaken the consequences of a
formula like~(\ref{ex:intro}) including operator $\tcauses$, but the
rule shapes

\

\prooftree
\mm  \,p \; \causes \; \mn  \,q \wedge \moo \, r 
\justifies
\mm  \,p \; \causes \; \mn  \,q  
\endprooftree

\

\noindent
since a formula like~(\ref{ex:intro2}) is not part of the
 logic. So, the price is writing one rule for each possible weakening
 relation. 






%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Conclusions}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

To reason on global applications, we have introduced the temporal
logic DSTL. Models for DSTL are space--time diagrams describing the
behaviour of a set of components communicating asynchronously. The
logic has been introduced in two steps.  First, we have defined DSL, a
modal logic for localities that embeds the theories describing the
local states of each component into a theory of the distributed states
of the system. No notion of time or state transition is present at
this stage. To support reasoning in the logic, we have presented a
sound and complete axiom system. Then, we have added the temporal
operators, and the corresponding derivation rules. The contribution is
that it is possible to reason about properties that involve several
components, even in the absence of a global clock, which is a
meaningless notion in an asynchronous setting. The logic has been used
to reason on the properties of a simple secure communication system
and on an algorithm for the leader election.



Future work includes the extension of DSTL to predicate logic, the
introduction of an {\em event} operator, the study of compositionality
results, and a revision of the theorem prover Mark.  We foresee that
formulae in the 1$^{st}$ order extension will shape $\mm\,p(x)\causes
\mn\, q(x,y)$, and be interpreted as $\;\forall x. [\mm\,p(x)\causes
\exists y. \,\mn \, q(x,y)]$. This way, the semantics should
smoothly extend that of DSTL.  Compositionality results will permit to
derive the properties satisfied by a system from the properties
satisfied by its components when executed in isolation.  This requires
reasoning on the possible interferences due to communications from the
added components.







\begin{thebibliography}{10}

\bibitem{tesiAreces}
C.~Areces.
\newblock {\em Logic Engineering. The Case of Description and Hybrid Logics}.
\newblock PhD thesis, ILLC, University of Amsterdam, The Netherlands., 2000.

\bibitem{CardCair1e2}
L.~Caires and L.~Cardelli.
\newblock A {S}patial {L}ogic for {C}oncurrency ({P}art {I} and {II}).
\newblock Part 1: To appear in Journal of Information and Computation special
  issue on TACS 2001. Part2: Proc. CONCUR'2002, LNCS 2421, Springer-Verlag.

\bibitem{CG00:logic-for-MA}
L.~Cardelli and A.~Gordon.
\newblock {Anytime, anywhere --- modal logics for mobile ambients}.
\newblock In {\em Proceedings of POPL '00}, pages 365--377. ACM, 2000.

\bibitem{CG00:mobile-ambients}
L.~Cardelli and A.D. Gordon.
\newblock Mobile ambients.
\newblock {\em Theoretical Computer Science}, 240(1):177--213, 2000.
\newblock An extended abstract appeared in \emph{Proceedings of FoSSaCS '98},
  number 1378 of Lecture Notes in Computer Science, pages 140-155, Springer,
  1998.

\bibitem{chmi88}
K.M. Chandy and J.~Misra.
\newblock {\em Parallel {P}rogram {D}esign: {A} {F}oundation}.
\newblock Addison-Wesley, Reading Mass., 1988.

\bibitem{EhrichDalLibro}
H.-D. Ehrich, C.~Caleiro, A.~Sernadas, and G.~Denker.
\newblock Logics for specifying concurrent information systems.
\newblock In J.~Chomicki and G.~Saake, editors, {\em Logic for Databases and
  Information Systems}, pages 167--198. Kluver Academic Publishers, 1998.

\bibitem{fhmv95}
R.~Fagin, J.~Halpern, Y.~Moses, and M.~Vardi.
\newblock {\em Reasoning {A}bout {K}nowledge}.
\newblock MIT Press, 1995.

\bibitem{denver}
G.~Ferrari, C.~Montangero, L.~Semini, and S.~Semprini.
\newblock Refinement {C}alculus for {M}obility: expressing security policies.
\newblock In J.~Vitek, editor, {\em Workshop on Distributed Object Security},
  Denver, Co, 1999.

\bibitem{adhoc}
G.~Ferrari, C.~Montangero, L.~Semini, and S.~Semprini.
\newblock Ad {H}oc {N}etwork {A}pplications: {S}pecification, {D}esign, and
  {V}erification in mob$_{adtl}$.
\newblock In G.-C. Roman and G.P. Picco, editors, {\em Proc. ICSE'01 Workshop
  on Software Engineering and Mobility}, Toronto, CA, 13,14 May 2001.

\bibitem{mark}
G.~Ferrari, C.~Montangero, L.~Semini, and S.~Semprini.
\newblock Mark, a reasoning kit for mobility.
\newblock {\em Automated Software Engineering}, 9(2):137--150, Apr 2002.

\bibitem{wits00Corto}
G.Ferrari, C.Montangero, L.Semini, and S.Semprini.
\newblock Multiple {S}ecurity {P}olicies in {M}ob$_{adtl}$.
\newblock In {\em Proc. Work. on Issues in the Theory of Security}, Geneva,
  2000.

\bibitem{LogKatz}
S.~Katz and D.~Peled.
\newblock Interleaving set temporal logic.
\newblock {\em Theoretical Computer Science}, 75(3):263--287, 1990.

\bibitem{lprm95}
K.Lodaya, R.Parikh, R.Ramanujam, and P.S.Thiagarajan.
\newblock A {L}ogical {S}tudy of {D}is- tributed {T}ransition {S}ystems.
\newblock {\em Information and Computation}, 119(1):91--118, '95.

\bibitem{Kreger}
H.~Kreger.
\newblock Web {Services Conceptual Architecture}.
\newblock IBM Software Group, May 2001.
\newblock www-4.ibm.com/software/solutions/webservices/pdf/WSCA.pdf.

\bibitem{lamport78}
L.Lamport.
\newblock Time, clocks, and the ordering of events in a distributed system.
\newblock {\em Communications of the ACM}, 21(7):558--565, Jul 1978.

\bibitem{LodRamThi92Corto}
Lodaya, Ramanujam, and Thiagarajan.
\newblock Temporal logics for communicating sequential agents: {I}.
\newblock {\em Int. Journal of Found. of Computer Science}, 3(2):117--159, '92.

\bibitem{loretiTOCL}
M.~Loreti and R.~De Nicola.
\newblock A modal logic for mobile agents.
\newblock ACM Transaction on Computational Logic (to apperar).

\bibitem{masini92}
A.~Masini and A.~Maggiolo-Schettini.
\newblock {TTL}: A formalism to describe local and global properties of
  distributed systems.
\newblock {\em Informatique th\'eorique et Applications/Theoretical Informatics
  and Applications}, 26(2):115--149, 1992.

\bibitem{merz03}
S.~Merz, M.~Wirsing, and J.~Zappe.
\newblock A spatio--temporal logic for the specification and refinement of
  mobile systems.
\newblock In M.~Pezz\'e, editor, {\em Proc. FASE 2003}, volume 2621 of {\em
  Lecture Notes in Computer Science}, pages 87--101. Springer-Verlag, 2003.

\bibitem{tesiAmontanari}
A.~Montanari.
\newblock {\em Metric and Layered Temporal Logic for Time Granularity}.
\newblock PhD thesis, University of Amsterdam, 1996.
\newblock Chapter 3.

\bibitem{isawCorto}
C.~Montangero and L.~Semini.
\newblock Refining by {A}rchitectural {S}tyles or {A}rchitecting by
  {R}efinements.
\newblock In {\em 2nd Int. Software Architecture Workshop, Proc. of the SIGSOFT
  '96 Workshops}, pages 76--79, San Francisco, CA, Oct 1996. ACM Press.

\bibitem{fmics01}
C.~Montangero and L.~Semini.
\newblock Software specification and design: from formal methods to standard
  middleware.
\newblock In {\em Proc. 6th ERCIM Inter. Workshop on Formal Methods for
  Industrial Critical Systems (FMICS'01)}, 2001.

\bibitem{time02}
C.~Montangero and L.~Semini.
\newblock Distributed states logic.
\newblock In {\em 9$^{th}$ International Symposium on Temporal Representation
  and Reasoning}, Manchester, UK, July 2002. IEEE CS Press.

\bibitem{coord99c}
C.~Montangero and L.~Semini.
\newblock Composing {S}pecifications for {C}oordination.
\newblock In P.~Ciancarini and A.~Wolf, editors, {\em Proc. {COORDINATION 99}},
  volume 1594 of {\em LNCS}, pages 118--133, Amsterdam, April 99.
  Springer-Verlag.

\bibitem{CLR2}
Microsoft .NET.
\newblock at http://research.microsoft.com.

\bibitem{CatSynch}
C.~Palamidessi.
\newblock Comparing the expressive power of the synchronous and the
  asynchronous pi-calculus.
\newblock Mathematical {S}tructures in {C}omputer {S}cience. {T}o appear.
\newblock http://www.cse.psu.edu/\~catuscia/papers/pi\_calc/mscs.ps.

\bibitem{PiWo}
Pinter and Wolper.
\newblock A temporal logic for reasoning about partially ordered
  specifications.
\newblock In {\em Proc. 3$^{th}$ ACM Principles of Distributed Computing},
  pages 28--37, Vancouver, B.C., 1984.

\bibitem{Rama96}
R.~Ramanujam.
\newblock Locally linear time temporal logic.
\newblock In {\em Proc. $11^{th}$ IEEE Symp. on Logic In Computer Science},
  pages 118--127. IEEE Computer Society, 1996.

\bibitem{sgarrascico}
L.~Semini and C.~Montangero.
\newblock A {R}efinement {C}alculus for {T}uple {S}paces.
\newblock {\em Science of Computer Programming}, 34:79--140, 1999.

\bibitem{Thiaga94}
P.~S. Thiagarajan.
\newblock A trace based extension of linear time temporal logic.
\newblock In {\em Proceedings, Ninth Annual {IEEE} Symposium on Logic in
  Computer Science}, pages 438--447, Paris, Jul 1994. IEEE Computer Society
  Press.

\bibitem{Thiaga98DVL}
P.~S. Thiagarajan and J.~G. Henriksen.
\newblock Distributed versions of linear time temporal logic: {A} trace
  perspective.
\newblock In W.~Reisig and G.~Rozenberg, editors, {\em Lectures on Petri Nets
  I: Basic Models, Advances in Petri Nets}, volume 1491 of {\em Lecture Notes
  in Computer Science}, pages 643--681. Springer-Verlag, 1998.

\bibitem{CSHARP}
C.~Wille.
\newblock {\em Presenting {C}\#}.
\newblock SAMS Publishing, 2000.

\end{thebibliography}


%\bibliographystyle{plain}
%\bibliography{../../tesi/tesi}

\newpage 

\appendix


\noindent
{\Large \bf Appendix}

\

\noindent
{\large \bf Proofs from Section~\ref{dslaxsys}}

\


\noindent
{\bf Axiom 4}

\


{\small
\prooftree
\bar{\mm} (\bar{\mm}  F \law   F)
\justifies
\bar{\mm}\bar{\mm}   F \law \bar{\mm}  F
\using{K}
\endprooftree
}

\

\


\noindent
{\bf D1}

\

{\small
\prooftree
\prooftree
\prooftree
\prooftree
\bar{\mm} (\bar{\mm} \sim F \lraw  \sim F)
\justifies
\bar{\mm}\bar{\mm}  \sim F \lraw \bar{\mm}  \sim F
\using{K}
\endprooftree
\justifies
\sim \mm  \sim \sim \mm  \sim  \sim F \lraw \sim \mm  \sim  \sim F
\endprooftree
\justifies
\sim \mm   \mm   F \lraw \sim \mm   F
\endprooftree
\justifies
\mm F \ \lraw \ \mm\mm F
\endprooftree
}

\

\

\noindent
{\bf D2} 
We show that  $\mm  (F\wedge F') \: \raw \:  \mm  F$,  $\mm  (F\wedge F')
\: \raw \:  \mm  F'$ is proved analogously. 

\

{\small
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
F\wedge F' \: \raw \: F
\justifies
\sim (F\wedge F') \: \law \: \sim  F
\endprooftree
\justifies
\bar{\mm} (\sim (F\wedge F') \: \law \: \sim  F)
\using{Nec}
\endprooftree
\justifies
\bar{\mm} \sim (F\wedge F') \: \law \: \bar{\mm}  \sim  F
\using{K}
\endprooftree
\justifies
\sim \mm \sim \sim (F\wedge F') \: \law \: \sim \mm  \sim \sim  F
\endprooftree
\justifies
\mm  (F\wedge F') \: \raw \:  \mm  F
\endprooftree
}

\


\


\noindent
{\bf D3}


\

{\small
\prooftree %0
\prooftree %1
\prooftree %2
\prooftree %3
\bar{\mm} (F\raw F') \quad
\prooftree %4
(F\raw F') \raw (\sim F' \raw \sim F)
\justifies %4
\bar{\mm} (F\raw F') \raw \bar{\mm}(\sim F' \raw \sim F)
\using{\mbox{\small Nec,  K}} 
\endprooftree %4
\justifies %3
 \bar{\mm}(\sim F' \raw \sim F)
\using{\mbox{\small MP}} 
\endprooftree %3
\justifies %2
 \bar{\mm}\sim F' \raw \bar{\mm}\sim F
\using{\mbox{\small  K}} 
\endprooftree %2
\justifies %1
 \sim \mm F' \raw \sim \mm F
\using{\mbox{\small  Def}} 
\endprooftree %1
\justifies %0
  \mm F \raw  \mm F'
\using{\mbox{\small  PC}} 
\endprooftree %0
}



\

\


\noindent
{\bf D5}

\

{\small
\prooftree
\prooftree
\bar{\mm} (\bar{\mm} \sim F \lraw \sim F)
\justifies
\bar{\mm} (\sim {\mm} \sim \sim F \lraw \sim F)
\endprooftree
\justifies 
\bar{\mm} ( {\mm}  F \lraw  F)
\endprooftree
}



\newpage


\noindent
{\bf D6} For $A=F\raw F'$ , $B=F'\raw F''$, and $C=F\raw F''$

\

{\small
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
A\wedge B \raw C
\justifies
\sim A \vee \sim B \vee C
\endprooftree
\justifies
 A \raw (B \raw C)
\endprooftree
\justifies
\bar{\mm} A \raw \bar{\mm} (B \raw C)
\using{Nec,K}
\endprooftree
\justifies
\bar{\mm} A \raw  (\bar{\mm}B \raw \bar{\mm}C)
\using{K}
\endprooftree
\justifies
\sim \bar{\mm} A \vee \sim \bar{\mm}B \vee  \bar{\mm}C
\endprooftree
\justifies
\sim (\bar{\mm} A \wedge \bar{\mm}B) \vee  \bar{\mm}C
\endprooftree
\justifies
(\bar{\mm} A \wedge \bar{\mm}B) \raw  \bar{\mm}C
\endprooftree
}

\

\


\noindent
{\bf D7}  We prove  $\mm(F\vee F' )\raw (\mm F \vee \mm F')$ on the left, 
and $\mm(F\vee F' )\law (\mm F \vee \mm F')$ on the right.

\



\

\noindent
{\small
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
\prooftree
(A\wedge B) \raw (A\wedge B)
\justifies
\sim A \vee \sim B \vee (A\wedge B)
\endprooftree
\justifies
 A \raw (B \raw (A\wedge B))
\endprooftree
\justifies
\bar{\mm} A \raw \bar{\mm} (B \raw (A\wedge B))
\using{Nec,K}
\endprooftree
\justifies
\bar{\mm} A \raw  (\bar{\mm}B \raw \bar{\mm}(A\wedge B))
\using{K}
\endprooftree
\justifies
\sim \bar{\mm} A \vee \sim \bar{\mm}B \vee  \bar{\mm}(A\wedge B)
\endprooftree
\justifies
\sim (\bar{\mm} A \wedge \bar{\mm}B) \vee  \bar{\mm}(A\wedge B)
\endprooftree
\justifies
(\bar{\mm} A \wedge \bar{\mm}B) \raw  \bar{\mm}(A\wedge B)
\endprooftree
\justifies
(\sim \mm \sim A \wedge \sim \mm \sim B) \raw  \sim \mm \sim (A\wedge B)
\endprooftree
\justifies
\sim (\mm \sim A \vee \mm \sim B) \raw  \sim \mm (\sim A \vee \sim B)
\endprooftree
\justifies
(\mm \sim A \vee \mm \sim B) \law   \mm (\sim A \vee \sim B)
\endprooftree
\justifies
\mm(F\vee F' )\raw (\mm F \vee \mm F')
\using{\begin{array}{l}F\equiv \sim A\\ F'\equiv \sim B\end{array}}
\endprooftree
}
\hspace{-1cm}
{\small
\prooftree
\prooftree
\prooftree
F \raw (F\vee F')
\justifies
\bar{\mm} (F \raw (F\vee F'))
\using{Nec}
\endprooftree
D3
\justifies
\mm F \raw \mm(F\vee F')
\using{MP}
\endprooftree
\prooftree
\prooftree
F' \raw (F\vee F')
\justifies
\bar{\mm} (F' \raw (F\vee F'))
\using{Nec}
\endprooftree
 D3
\justifies
\mm F' \raw \mm(F\vee F')
\using{MP}
\endprooftree
\justifies
(\mm F \vee \mm F') \raw \mm(F\vee F')
\endprooftree
}

\

\


\noindent
{\bf  D8}
If we prove  $\bar{\mm} ((\mm F\wedge \mm F')\raw (F\wedge F'))$ 
and 
%
$\bar{\mm} ((F\wedge F')\raw \mm (F\wedge F'))$ 
%
then we can apply D6 and conclude.
The second formula  is an instance of D5, we prove the first one:

\

{\small
\prooftree
(\mm F\raw F \; \wedge \; \mm F'\raw F') \raw (\mm F\wedge \mm F'  \; \raw \; F\wedge F')
\justifies
\bar{\mm} (\mm F\raw F \; \wedge \; \mm F'\raw F') \raw  \bar{\mm}  (\mm F\wedge \mm F'  \; \raw \; F\wedge F')
\using{Nec,K}
\endprooftree
}

\


\


{\small
\prooftree
\prooftree
\prooftree
D5
\justifies
\bar{\mm} (\mm F\raw F) \; \wedge \; \bar{\mm}(\mm F'\raw F')
\endprooftree
\quad \prooftree 
	D7
	\justifies
	(\bar{\mm}F \wedge \bar{\mm}F') \raw \bar{\mm}(F\wedge F')
	\endprooftree
\justifies
\bar{\mm} (\mm F\raw F \; \wedge \; \mm F'\raw F')
\using{MP}
\endprooftree
\justifies
\bar{\mm} (\mm F\wedge \mm F' \; \raw F \wedge F')
\using{MP, \mbox{with the conclusions of the previous derivation} }
\endprooftree
}



\newpage


\noindent
{\large \bf Proof of the Notification Rule}

\



\begin{center}
{\small
\noindent
\prooftree
F \because G \quad G \causes \mm G^{\prime} \quad \stable \mm G^{\prime}
\justifies
F \wedge \mm \top \causes \mm G^{\prime}
\using{\bf Notif}
\endprooftree 
}
\end{center}

\

\noindent
Let $ds$ be a distributed state satisfying $F\wedge \mm\top$, we have
that:



\vspace{-0.6cm}

\begin{eqnarray*}
ds \models F\wedge \mm\top & \Raw & ds \models F\\
 & \Raw & \exists ds^{\prime} \leq  ds. \  ds^{\prime}\models G
				\quad \quad\quad \quad (since F \because G)\\
 & \Raw & \exists ds^{\prime\prime} \geq ds^{\prime}. \
	ds^{\prime\prime}\models \mm G^{\prime} \;\quad \quad (since G
	\causes \mm G^{\prime})
\end{eqnarray*}


\noindent
Summing up, $\forall ds\models F \ \exists ds^{\prime\prime}\models
\mm G^{\prime}$. 

Now, $ds^{\prime\prime}\models \mm G^{\prime}$ implies that $ \exists
s \in ds^{\prime\prime} \cap S_m$ with $\{s\} \models \mm G^{\prime}$.
Stability of $\mm G^{\prime}$ guarantees that for any state
$s^{\prime}\in S_m$ that follows $s$, $\{s^{\prime}\} \models \mm
G^{\prime}$. So, we can build a distributed state which follows any
$ds$ satisfying $F\wedge \mm\top$ and satisfies $\mm G^{\prime}$.


\

\

\noindent
{\large \bf Proof of the Confluence Rule} 


\begin{center}
{\small
\noindent
\prooftree
\stable  \mm F \quad \stable  \mm F^{\prime} 
\justifies
\mm F\wedge \mm F^{\prime}  \ \raw \ \mm (F\wedge F^{\prime})
\using{\bf Conf}
\endprooftree 
}
\end{center}

\

\noindent
Let $ds$ be a distributed state satisfying $\mm F\wedge \mm F^{\prime}$:

\vspace{-0.6cm}

\begin{eqnarray*}
ds \models \mm F\wedge \mm F^{\prime} & \LRaw & 
	ds \models \mm F \mbox{ and } ds \models \mm F^{\prime}\\
 & \LRaw & \exists s \in ds \cap S_m. \ \{s\} \models  F   \mbox{ and }
   \exists   s^{\prime}\in ds \cap S_m. \ \{s^{\prime}\} \models  F^{\prime}
\end{eqnarray*}


\noindent
Let $\{s\} \geq \{s^{\prime}\}$ (the case $\{s\} \leq \{s^{\prime}\}$ is
symmetric), for the stability of $F^{\prime}$ we have that also
$\{s\}$ satisfies $F^{\prime}$:

\vspace{-0.6cm}

\begin{eqnarray*}
\{s\} \models F   \mbox{ and } \{s\} \models F^{\prime} & \LRaw & 
	\{s\} \models F \wedge  F^{\prime} \\
 & \LRaw & ds \models \mm (F\wedge F^{\prime})
\end{eqnarray*}


\

\noindent
{\large \bf Proof of Cor1 and Cor2}

\

\begin{center}
{\small
\noindent
\prooftree
F\causes G\vee  G^{\prime} \quad 
  \prooftree
	\prooftree
	G\causes F^{\prime} \quad F^{\prime} \raw F^{\prime} \vee G^{\prime}
	\justifies
	G\causes F^{\prime} \vee G^{\prime}
	\using{\bf LSW}
	\endprooftree
	\quad 
	\prooftree
	G^{\prime} \causes G^{\prime} \quad 
		G^{\prime} \raw F^{\prime} \vee G^{\prime}
	\justifies
	G^{\prime} \causes F^{\prime} \vee G^{\prime}
	\using{\bf LSW}
	\endprooftree
  \justifies
  G \vee G^{\prime} \causes F^{\prime} \vee G^{\prime}
   \using{\bf LPD}
  \endprooftree
\justifies
F\causes F^{\prime} \vee G^{\prime}
\using{\bf LTR}
\endprooftree
}
\end{center}



\


\begin{center}
{\small
\noindent
\prooftree
  \prooftree
	\prooftree
	F \causes G \wedge G^{\prime} \quad  G \wedge G^{\prime}\raw G
	\justifies
	F \causes G
	\using{\bf LSW}
	\endprooftree
	\quad 
	G \causes F^{\prime} 
  \justifies
  F \causes  F^{\prime} 
   \using{\bf LTR}
  \endprooftree
\quad 
  \prooftree
  F \causes G \wedge G^{\prime} \quad  G \wedge G^{\prime}\raw G^{\prime}
   \justifies
  F \causes  G^{\prime}
  \using{\bf LSW}
   \endprooftree
\justifies
F\causes F^{\prime} \wedge G^{\prime}
\using{\bf LCC}
\endprooftree
}
\end{center}




\end{document}







xy.tex
%% xy.tex from $Id: xy.doc,v 3.2 1995/09/19 18:22:27 kris Exp kris $
%%
%% Basic Xy-pictures: Xy-pic bootstrap and kernel macros.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined\else\message{not reloaded}\endinput\fi
\let\xyloaded=\relax
\message{Bootstrap\string'ing\string:}
{\catcode96 12\catcode`\#6\catcode`\.12\catcode`\:12\catcode`\'12\catcode`\@11
\ifx\xywarnifdefined\undefined\else \immediate\write16{}%
 \immediate\write16{Xy-pic Warning: \string\xywarnifdefined\space redefined.}%
 \immediate\write16{}\fi
\gdef\xywarnifdefined#1{\ifx#1\undefined\else \immediate\write16{}%
 \immediate\write16{Xy-pic Warning: `\string#1' redefined.}%
 \immediate\write16{}\fi}
\xywarnifdefined\xydef@ \gdef\xydef@#1{\xywarnifdefined#1\def#1}
\xywarnifdefined\xylet@ \gdef\xylet@#1{\xywarnifdefined#1\let#1}
\xywarnifdefined\xynew@
 \gdef\xynew@#1#2{\xywarnifdefined#2\csname new#1\endcsname#2}}
\message{catcodes\string,}
\xywarnifdefined\xyuncatcodes
\xywarnifdefined\xyreuncatcodes \def\xyreuncatcodes{\edef\xyuncatcodes{%
 \catcode92 0 \catcode123 1 \catcode125 2 \catcode37 14
 \catcode 9 \the\catcode 9 \catcode10 \the\catcode10 \catcode12 \the\catcode12
 \catcode35 \the\catcode35 \catcode36 \the\catcode36 \catcode38 \the\catcode38 
 \catcode43 \the\catcode43 \catcode45 \the\catcode45 \catcode46 \the\catcode46 
 \catcode47 \the\catcode47 
 \catcode60 \the\catcode60 \catcode61 \the\catcode61 \catcode62 \the\catcode62 
 \catcode64 \the\catcode64 \catcode96 \the\catcode96
 \newlinechar \the\newlinechar \endlinechar \the\endlinechar }}
\xyreuncatcodes
\xywarnifdefined\xycatcodes \def\xycatcodes{%
 \catcode 9 10
 \catcode35 6 \catcode 36 3 \catcode 38 4
 \catcode43 12 \catcode 45 12 \catcode 46 12 \catcode 47 12
 \catcode60 12 \catcode 61 12 \catcode 62 12
 \catcode64 11 \catcode 96 12 }
\xycatcodes
\message{docmode,}
{\catcode`\|0 \xywarnifdefined|DOCMODE
\gdef|DOCMODE#1{\ifx(#1\relax \xycatcodes \expandafter\ignorespaces
 \else \skipspecials@ \expandafter\docm@\fi}%
\xywarnifdefined\skipspecials@
\gdef\skipspecials@{%
 \catcode`\\12 \catcode`\{12 \catcode`\}12 \catcode`\#12 \catcode`\%12
 \catcode`\^^L12 \endlinechar`\^^J }%
\catcode`\/=12 \lccode`\/`\\%
\lccode`\D`\D \lccode`\O`\O \lccode`\C`\C \lccode`\M`\M \lccode`\E`\E
\lowercase{%
\xywarnifdefined\docm@ \gdef\docm@{\docm@i}%
\xywarnifdefined\docm@i \gdef\docm@i#1^^J{\docm@ii#1/DOCMODE\docm@iii}%
\xywarnifdefined\docm@ii
 \gdef\docm@ii#1/DOCMODE{\def\next@{#1}\futurelet\next\docm@iii}%
\xywarnifdefined\docm@iii \gdef\docm@iii#1\docm@iii{%
 \ifx\next\docm@iii \let\next\next@ \docecho@ \let\next@\docm@
 \else\ifx\next@\empty \let\next@\docfinish@
 \else \edef\next@{\noexpand\docm@iv\next@/DOCMODE#1\noexpand\docm@iv}%
 \fi\fi \next@}%
\xywarnifdefined\docm@iv
 \gdef\docm@iv#1/DOCMODE\docm@iv{\def\next{#1}\docecho@ \docm@}}%
\xywarnifdefined\docecho@ \global\let\docecho@\relax
\xywarnifdefined\docfinish@ \gdef\docfinish@{\xyuncatcodes|DOCMODE\next}}
\xydef@\xydefcsname@#1{\DN@{#1}\DNii@##1{%
 \ifx ##1\relax\else \xywarning@{`\string##1\string' redefined}\fi \def##1}%
 \expandafter\nextii@\csname\codeof\next@\endcsname}
\xydef@\xyletcsnamecsname@#1#2{\def\1{#1}\def\2{#2}\DN@##1##2{%
 \ifx ##1\relax\else \xywarning@{`\string##1\string' redefined}\fi
 \let##1=##2}%
 \expandafter\expandafter\expandafter\next@
 \expandafter\csname\expandafter\codeof\expandafter\1\expandafter\endcsname
 \csname\codeof\2\endcsname}
\xywarnifdefined\codeof
\xywarnifdefined\codeof@
{\catcode`\:=12
 \gdef\codeof#1{\expandafter\codeof@\meaning#1<-:}
 \gdef\codeof@#1:->#2<-:{#2}}
\xywarnifdefined\addAT@
\xywarnifdefined\addHASH@
\xywarnifdefined\addDOLL@
\xywarnifdefined\addAND@
\xywarnifdefined\addRQ@
\xywarnifdefined\addPLUS@
\xywarnifdefined\addDASH@
\xywarnifdefined\addDOT@
\xywarnifdefined\addLT@
\xywarnifdefined\addEQ@
\xywarnifdefined\addGT@
\xywarnifdefined\addLQ@
\xydef@\xymakeADD@#1#2 #3 {\ifnum\catcode#3=6 \def#1##1{##1#2#2}%
 \else \def#1##1{##1#2}\fi}
\xydef@\xyrecat@{\xymakeADD@\addAT@}
\xydef@\xyrecat{\xyrecat@}
\xydef@\xyresetcatcodes{\def\xyrecat{\xyrecat@}\xyreuncatcodes
 \input xyrecat \relax \xyuncatcodes}
\xyuncatcodes \xyresetcatcodes \xycatcodes
\input xyidioms
\xydef@\stripRCS$#1${\stripRCS@#1: @@ @@@}
\xydef@\stripRCS@#1: #2@ #3@@@{%
 \ifx @#2\string?\else\ifx :#2\else\stripRCS@@#2\fi\fi}
\xydef@\stripRCS@@#1 #2: @{#1}
 \edef\next{\stripRCS$Revision: 3.2 $}
 \edef\next@{\stripRCS$Locker: $}
\xylet@\xyversion=\next
\def\next{ @}\ifx\next\next@
 \edef\next{\stripRCS$Date: 1995/09/19 18:22:27 $}
\else\edef\xyversion{\xyversion+}
 \edef\next{\number\year/\ifnum\month<10 0\fi\number\month
 /\ifnum\day<10 0\fi\number\day}\fi
\xylet@\xydate=\next
\xydef@\Xygreet@{%
 \W@{}%
 \W@{ Xy-pic version \xyversion\space<\xydate>}%
 \W@{ Copyright (c) 1991-1995 by Kristoffer H. Rose <kris@diku.dk>}%
 \W@{ Xy-pic is free software: see the User\string's Guide for details.}%
 \W@{}}
\Xygreet@
\expandafter\everyjob\expandafter{\the\everyjob\Xygreet@}
\message{Loading kernel:}
\xydef@\Xy{\leavevmode
 \hbox{\kern-.1em X\kern-.3em\lower.4ex\hbox{Y\kern-.15em}}}
\xylet@\XY=\Xy
\message{messages;}
\xywarnifdefined\thelineno@
\ifx\inputlineno\undefined \edef\thelineno@{\string?}
\else \def\thelineno@{\the\inputlineno}\fi
\xydef@\xytracelineno@{ \string[\jobname:\thelineno@\string]}
\xydef@\xywarning@#1{{\newlinechar=`\^^J%
 \W@{}\W@{Xy-pic Warning: #1\xytracelineno@.}\W@{}}}
\xydef@\xyerror@#1#2{\if\inxy@\xy@{ERROR #1}{}\fi
 {\def\2{#2}\newlinechar=`\^^J%
 \ifx\2\empty \errhelp{See the Xy-pic manual for further information.}%
 \else \errhelp{#2}\fi
 \errmessage{Xy-pic error: #1}}}
\xydef@\xybug@#1{{\newlinechar=`\^^J%
 \errhelp{This is a bug in Xy-pic and should not happen!^^J%
If it did then please send a bug report with the offending Xy-pic code^^J%
to the author of Xy-pic, kris@diku.dk.}%
 \errmessage{Xy-pic BUG: #1 -- notify kris@diku.dk.}}}
\message{fonts;}
\xydef@\xyfont@#1{\ifx#1\undefined \DN@{\global\font#1}\expandafter\next@
 \else \xywarning@{Using previously loaded \string#1\space font}\fi}
\xyfont@\xydashfont=xydash10
\xydef@\xydashl@{\fontdimen6\xydashfont}
\xydef@\xydashh@{\fontdimen5\xydashfont}
\xydef@\xydashw@{\fontdimen8\xydashfont}
\xyfont@\xyatipfont=xyatip10
\xyfont@\xybtipfont=xybtip10
\xyfont@\xybsqlfont=xybsql10
\xydef@\xybsqll@{\fontdimen6\xybsqlfont}
\xydef@\xybsqlh@{\fontdimen5\xybsqlfont}
\xydef@\xybsqlw@{\fontdimen8\xybsqlfont}
\xyfont@\xycircfont=xycirc10
\message{allocations:}
\message{state,}
\xynew@{dimen}\X@c
\xynew@{dimen}\Y@c
\xynew@{dimen}\U@c
\xynew@{dimen}\D@c
\xynew@{dimen}\L@c
\xynew@{dimen}\R@c
\xynew@{toks}\Edge@c
\xynew@{dimen}\X@p
\xynew@{dimen}\Y@p
\xynew@{dimen}\U@p
\xynew@{dimen}\D@p
\xynew@{dimen}\L@p
\xynew@{dimen}\R@p
\xynew@{toks}\Edge@p
\xynew@{dimen}\X@origin \X@origin=\z@
\xynew@{dimen}\Y@origin \X@origin=\z@
\xynew@{dimen}\X@xbase \X@xbase=1mm
\xynew@{dimen}\Y@xbase \Y@xbase=\z@
\xynew@{dimen}\X@ybase \X@ybase=\z@
\xynew@{dimen}\Y@ybase \Y@ybase=1mm
\xynew@{dimen}\X@min
\xynew@{dimen}\Y@min
\xynew@{dimen}\X@max
\xynew@{dimen}\Y@max
\xynew@{box}\lastobjectbox@
\xynew@{box}\zerodotbox@
\setbox\zerodotbox@=\hbox{\dimen@=.5\xydashw@
 \kern-\dimen@ \vrule width\xydashw@ height\dimen@ depth\dimen@}
\wd\zerodotbox@=\z@ \ht\zerodotbox@=\z@ \dp\zerodotbox@=\z@
\xynew@{dimen}\almostz@ \almostz@=50sp
\xydef@\zz@#1{\ifdim#1<\z@-\fi#1<\almostz@\relax}
\xynew@{if}\iftmp@
\message{direction,}
\xynew@{dimen}\d@X
\xynew@{dimen}\d@Y
\xydef@\sd@X{}
\xydef@\sd@Y{}
\xynew@{count}\K@ \K@=1024
\xynew@{count}\KK@ \KK@=32
\xynew@{count}\Direction
\xynew@{dimen}\K@dXdY
\xynew@{dimen}\K@dYdX
\xydef@\cosDirection{}
\xydef@\sinDirection{}
\xywarnifdefined\DirectionChar
\xywarnifdefined\SemiDirectionChar
\xynew@{read}\xyread@
\xynew@{write}\xywrite@
\xynew@{count}\csp@
\xynew@{dimen}\quotPTK@
\message{utility macros;}
\xydef@\addtotoks@#1{\toks@=\expandafter{\the\toks@#1}}
\xydef@\xyinputorelse@#1#2{%
 \expandafter\let\expandafter\next@\csname#1loaded\endcsname
 \ifx\next@\empty \let\next@=\relax \else
 \openin\xyread@=#1 \ifeof\xyread@ \DN@{\openin\xyread@=#1.doc
 \ifeof\xyread@ \DN@{#2}\else \DN@{\closein\xyread@\input#1.doc }\fi \next@}%
 \else \DN@{\closein\xyread@\input#1 }\fi\fi \next@}
\global\csp@=\z@
\xydef@\enter@#1{\global\advance\csp@\@ne
 \expandafter\xdef\csname cs@\number\csp@\endcsname{#1}\ignorespaces}
\xydef@\nter@#1{\global\advance\csp@\@ne
 \expandafter\gdef\csname cs@\number\csp@\endcsname{#1}\ignorespaces}
\xydef@\dontleave@{\csname cs@\number\csp@\endcsname}
\xydef@\unenter@{\global\advance\csp@\m@ne}
\xydef@\leave@{\expandafter\unenter@\csname cs@\number\csp@\endcsname}
\quotPTK@=\p@ \divide\quotPTK@\K@
\xylet@\quotsign@@=\empty
\xywarnifdefined\removePT@
{\catcode`p=12 \catcode`t=12 \gdef\removePT@#1pt{#1}}
\xydef@\quotient@#1#2#3{\A@=#2\relax \B@=#3\relax
 \ifdim\A@<\z@\def\quotsign@@{-}\else\def\quotsign@@{+}\fi
 \ifdim\quotsign@@\A@<15pt \multiply\A@\K@
 \else\ifdim\quotsign@@\A@<511pt \multiply\A@\KK@ \divide\B@\KK@
 \else \divide\B@\K@ \fi\fi
 \ifdim\ifdim\B@<\z@-\fi\B@<\quotPTK@ \xywarning@{division overflow}%
 \else \advance\A@.5\B@ \divide\A@\B@ \fi
 \multiply\A@\quotPTK@ \edef#1{\expandafter\removePT@\the\A@}}
\xydef@\quotient@@#1#2#3{\A@=#2\relax \B@=#3\relax
 \multiply\A@\KK@ \divide\B@\KK@ \divide\B@ 8
 \ifdim\B@=\z@\else \advance\A@.5\B@ \divide\A@\B@ \fi
 \B@=.125\quotPTK@ \multiply\A@\B@ \edef#1{\expandafter\removePT@\the\A@}}
\xydef@\loop@#1\repeat@{\def\body@{#1}\iterate@}\xylet@\repeat@=\fi
\xydef@\iterate@{\body@\expandafter\iterate@\else\fi}
\xydef@\xyinitial@#1#2{\DN@{#1}%
 \xyerror@{command used out of context: \codeof\next@}{}}
\xylet@\xy@=\xyinitial@
\xylet@\oxy@=\xy@
\xydef@\inxy@{T\ifx\xy@\xyinitial@ F\else T\fi}
\xydef@\xyxy@@ix@{\begingroup
 \xyuncatcodes\afterassignment\endgroup\global\toks9=}
\xydef@\xy@@{\xy@{}}
\xydef@\plainxy@{\let\xy@=\xyxy@ \let\oxy@=\xy@ \let\xy@@ix@=\xyxy@@ix@}
\message{pictures: \string\xy,}
\xydef@\xy{\ifmmode\expandafter\xymath@\else\expandafter\xynomath@\fi}
\xydef@\xymath@{\hbox\bgroup \dimen@=\the\fontdimen22\textfont\tw@ \xyinside@}
\xydef@\xynomath@{\hbox\bgroup \dimen@=\z@ \xyinside@}
\xydef@\xyinside@{%
 \aftergroup\xycheck@end
 \setboxz@h\bgroup
 \plainxy@
 \X@c=\z@ \Y@c=\z@ \czeroEdge@
 \X@p=\z@ \Y@p=\z@ \U@p=\z@ \D@p=\z@ \L@p=\z@ \R@p=\z@ \Edge@p={\zeroEdge}%
 \X@min=\hsize \X@max=-\hsize \Y@min=\hsize \Y@max=-\hsize
 \expandafter\POS\everyxy@@}
\xydef@\czeroEdge@{\U@c=\z@ \D@c=\U@c \L@c=\U@c \R@c=\U@c \Edge@c={\zeroEdge}}
\xydef@\xyxy@#1#2{#2}
\xywarnifdefined\everyxy
\expandafter\def\addEQ@\everyxy#1{\def\everyxy@@{#1}\ignorespaces}
\xylet@\everyxy@@=\empty
\xydef@\endxy{\if\inxy@\else\xyerror@{Unexpected \string\endxy}{}\fi
 \relax
 \dimen@=\Y@max \advance\dimen@-\Y@min
 \ifdim\dimen@<\z@ \dimen@=\z@ \Y@min=\z@ \Y@max=\z@ \fi
 \dimen@=\X@max \advance\dimen@-\X@min
 \ifdim\dimen@<\z@ \dimen@=\z@ \X@min=\z@ \X@max=\z@ \fi
 \edef\tmp@{\egroup
 \setboxz@h{\kern-\the\X@min\boxz@}%
 \ht\z@=\the\Y@max \dp\z@=-\the\Y@min \wdz@=\the\dimen@
 \noexpand\maybeunraise@ \raise\dimen@\boxz@
 \egroup \noexpand\xy@end
 \U@c=\the\Y@max \D@c=-\the\Y@min \L@c=-\the\X@min \R@c=\the\X@max}\tmp@}
\xydef@\maybeunraise@{\if\inxy@\else \dimen@ii=\dp\z@
 \ifdim\dimen@ii<\z@ \advance\dimen@\dimen@ii \fi\fi}
\xydef@\xycheck@end{\xyFN@\xycheck@end@}
\xydef@\xycheck@end@{\ifx\next\xy@end\DN@\xy@end{}\else\DN@{\xy@end}\fi\next@}
\xydef@\xy@end{%
 \xyerror@{An \string\xy\space environment is not closed correctly.}%
 {I expected \string\endxy. You probably have an umatched {} grouping.}}
\message{positions,}
\xydef@\POS{\afterPOS{}}
\xydef@\afterPOS#1{%
 \DN@##1{\def\afterPOS@{\def\afterPOS@{##1}#1}}%
 \expandafter\next@\expandafter{\afterPOS@}%
 \afterCOORD{\xyFN@\POS@}}
\xylet@\afterPOS@=\empty
\xydef@\afterCOORD#1{%
 \DN@##1{\def\afterCOORD@{\def\afterCOORD@{##1}#1}}%
 \expandafter\next@\expandafter{\afterCOORD@}%
 \afterVECTORorEMPTY{\xy@@\czeroEdge@ \afterCOORD@}{\xyFN@\COORD@}}
\xylet@\afterCOORD@=\empty
\xydef@\afterVECTORorEMPTY#1#2{%
 \DN@##1{\def\afterVECTOR@{\def\afterVECTOR@{##1}%
 \ifVECTORempty@\DN@{#2}\else\DN@{#1}\fi \next@}}%
 \expandafter\next@\expandafter{\afterVECTOR@}%
 \xyFN@\VECTOR@}
\xynew@{if}\ifVECTORempty@
\xylet@\afterVECTOR@=\empty
\xydef@\xyVECTOR@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\VECTOR@}%
 \else \ifcat A\noexpand\next \let\next@=\VECTOR@letter
 \else \let\next@=\VECTOR@other \fi\fi \next@}
\xylet@\VECTOR@=\xyVECTOR@
\def\notrelaxorelse@#1#2{\ifx#1\relax \expandafter#2\else\expandafter#1\fi}
\xydef@\VECTOR@letter{%
 \ifx a\next \expandafter\VECTOR@a \else \expandafter\CORNER@ \fi}
\xydef@\VECTOR@a a(#1){\xy@{a(#1)}{\vfromcartesianangle@{#1}}%
 \VECTORempty@false \afterVECTOR@}
\xydef@\CORNER@{%
 \xy@{}{\A@=-.5\L@c \advance\A@.5\R@c \B@=-.5\D@c \advance\B@.5\U@c
 \let\nextii@=\zeroit@}%
 \VECTORempty@true\CORNER@i}
\xydef@\zeroit@#1{#1=\z@}
\xydef@\CORNER@i{%
 \ifx D\next \DN@ D{\xy@{D}{\Y@c=-\D@c \nextii@\X@c \B@=\Y@c}\CORNER@ii}%
 \else\ifx U\next \DN@ U{\xy@{U}{\Y@c= \U@c \nextii@\X@c \B@=\Y@c}\CORNER@ii}%
 \else\ifx L\next \DN@ L{\xy@{L}{\X@c=-\L@c \nextii@\Y@c \A@=\X@c}\CORNER@ii}%
 \else\ifx R\next \DN@ R{\xy@{R}{\X@c= \R@c \nextii@\Y@c \A@=\X@c}\CORNER@ii}%
 \else\ifx C\next \DN@ C{\xy@{C}{\X@c= \A@ \Y@c= \B@}\CORNER@ii}%
 \else\ifx E\next \DN@ E{\xy@{E}{%
 \A@=\X@c \B@=\Y@c \the\Edge@c\z@ \advance\X@c-\A@ \advance\Y@c-\B@}%
 \CORNER@ii}%
 \else\ifx P\next \DN@ P{\xy@{P}{%
 \A@=\X@c \B@=\Y@c \the\Edge@c\thr@@ \advance\X@c-\A@ \advance\Y@c-\B@}%
 \CORNER@ii}%
 \else\ifx (\next
 \DN@(##1){\xy@{(##1)}{\X@c=##1\X@c \Y@c=##1\Y@c}\afterVECTOR@}%
 \else \let\next@=\afterVECTOR@
 \fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xydef@\CORNER@ii{\xy@@{\let\nextii@=\eat@}%
 \VECTORempty@false \xyFN@\CORNER@i}
\xydef@\VECTOR@other{%
 \addLT@\ifx \next
 \addGT@{\addLT@\DN@##1}{\xy@{<##1>}{\vfromabsolute@{##1}}%
 \VECTORempty@false\afterVECTOR@}%
 \else\ifx (\next
 \DN@({\xyFN@\VECTOR@other@open}%
 \else\ifx /\next
 \DN@/##1/{\xy@@ix@{{##1}}%
 \xy@{/##1/}{\expandafter\vfromslide@\the\toks9}%
 \VECTORempty@false\afterVECTOR@}%
 \else\ifx 0\next
 \DN@ 0{\xy@{0}{\X@c=\z@ \Y@c=\z@}\VECTORempty@false\afterVECTOR@}%
 \else
 \DN@{\VECTORempty@true\afterVECTOR@}%
 \fi\fi\fi\fi \next@}
\xydef@\VECTOR@other@open{%
 \ifx *\next \DN@{\VECTORempty@true \xyFN@\afterVECTOR@(}%
 \else
 \DN@##1){\xy@{(##1)}{\vfromcartesian@{##1}}\VECTORempty@false\afterVECTOR@}%
 \fi \next@}
\xydef@\xyCOORD@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\COORD@}%
 \else \ifcat A\noexpand\next \let\next@=\xyCOORD@letter
 \else \let\next@=\xyCOORD@other \fi\fi \next@}
\xylet@\COORD@=\xyCOORD@
\xydef@\xyCOORD@letter{%
 \ifx c\next
 \DN@ c{\xy@{c}{}\afterCOORD@}%
 \else\ifx p\next
 \DN@ p{\xy@{p}\cfromp@ \afterCOORD@}%
 \else\ifx x\next
 \DN@ x{\xy@{x}{\R@c=\X@xbase \U@c=\Y@xbase \intersect@}\afterCOORD@}%
 \else\ifx y\next
 \DN@ y{\xy@{y}{\R@c=\X@ybase \U@c=\Y@ybase \intersect@}\afterCOORD@}%
 \else\ifx s\next
 \DN@ s##1{\xy@{s{##1}}{\cfroms@{##1}}\afterCOORD@}%
 \else \let\next@=\afterCOORD@ \fi\fi\fi\fi\fi \next@}
\xydef@\xyCOORD@other{%
 \ifx "\next
 \DN@"##1"{\xy@{"##1"}{\cfromid@{##1}}\afterCOORD@}%
 \else\ifx \bgroup\next
 \DN@##1{\xy@{{##1}}{\enter@{\pfromthep@\basefromthebase@}}%
 \silencexy@ \POS##1\relax \unsilencexy@ \xy@@\leave@ \afterCOORD@}%
 \else\ifx (\next
 \DN@({\xyFN@\xyCOORD@other@open}%
 \else \let\next@=\afterCOORD@ \fi\fi\fi \next@}
\xynew@{if}\ifsilentxy@
\xydef@\silencexy@{%
 \ifsilentxy@ \nter@{}%
 \else \nter@{\silentxy@false \let\xy@=\unsilent@@xy@}
 \silentxy@true \let\unsilent@@xy@=\xy@ \def\xy@##1##2{\unsilent@@xy@{}{##2}}%
 \fi}
\xydef@\unsilencexy@{\leave@}
\xydef@\xyCOORD@other@open{%
 \ifx *\next
 \DN@*##1*){\xy@{(*}{\enter@{\pfromthep@\basefromthebase@}}%
 \POS##1\relax \xy@{*)}\leave@ \afterCOORD@}%
 \else \DN@{\xyFN@\afterCOORD@(}%
 \fi \next@}
\xydef@\xyPOS@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\POS@}%
 \else\addPLUS@\ifx \next
 \addPLUS@\DN@{\xy@+{\enter@\cplusthec@}%
 \afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
 \else\addDASH@\ifx \next
 \addDASH@\DN@{\xy@-{\enter@\cplusthec@}%
 \afterCOORD{\xy@@{\X@c=-\X@c \Y@c=-\Y@c\leave@}\xyFN@\POS@}}%
 \else\ifx !\next
 \DN@ !{\xy@!{\enter@\cskewthec@}\afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
 \else\addDOT@\ifx \next
 \addDOT@\DN@{\xy@.{\enter@\cmergethec@}%
 \afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
 \else\ifx ,\next
 \DN@ ,{\xy@,{\comma@@}\afterCOORD{\xyFN@\POS@}}%
 \else\ifx ;\next
 \DN@ ;{\xy@;{\swap@}\afterCOORD{\xyFN@\POS@}}%
 \else\ifx :\next
 \DN@ :{\xyFN@\POS@colon}%
 \else\addEQ@\ifx \next
 \addEQ@\DN@{\xyFN@\saveid@}%
 \else\ifx *\next
 \DN@ *{\xyFN@\POS@star}%
 \else \ifx ?\next
 \DN@?{\xy@?{}\afterPLACE{\xyFN@\POS@}}%
 \else \addAT@\ifx \next
 \addAT@\DN@{\xyFN@\STACK@}%
 \else
 \let\next@=\afterPOS@
 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xylet@\comma@@=\relax
\xylet@\POS@=\xyPOS@
\xydef@\POS@colon{\DNii@{\afterCOORD{\xyFN@\POS@}}%
 \ifx :\next \xy@{::}{\setbase@@\X@c\Y@c}\DN@:{\nextii@}%
 \else \xy@:{\setbase@\X@p\Y@p\X@c\Y@c}\let\next@=\nextii@ \fi
 \next@}
\xydef@\POS@star{%
 \ifx *\next
 \DN@*##1##{\nextii@{##1}}%
 \DNii@##1##2{\xy@@ix@{{##1}{##2}}%
 \xy@{**##1{##2}}{\expandafter\connect@\the\toks9}\xyFN@\POS@}%
 \else
 \DN@##1##{\nextii@{##1}}%
 \DNii@##1##2{\xy@@ix@{{##1}{##2}}%
 \xy@{*##1{##2}}{\expandafter\drop@\the\toks9}\xyFN@\POS@}%
 \fi
 \next@}
\xydef@\cfromp@{\X@c=\X@p \Y@c=\Y@p \U@c=\U@p \D@c=\D@p \L@c=\L@p \R@c=\R@p
 \Edge@c=\expandafter{\the\Edge@p}}
\xydef@\pfromc@{\X@p=\X@c \Y@p=\Y@c \U@p=\U@c \D@p=\D@c \L@p=\L@c \R@p=\R@c
 \Edge@p=\expandafter{\the\Edge@c}}
\xydef@\swapdimen@#1#2{\dimen@=#1\relax #1=#2\relax #2=\dimen@}
\xynew@{toks}\swaptoks@@
\xydef@\swap@{\swapdimen@\X@c\X@p \swapdimen@\Y@c\Y@p
 \swapdimen@\U@c\U@p\swapdimen@\D@c\D@p \swapdimen@\L@c\L@p\swapdimen@\R@c\R@p
 \swaptoks@@=\Edge@c \Edge@c=\Edge@p \Edge@p=\swaptoks@@}
\xydef@\vfromabsolute@#1{\vfromabsolute@@#1,@}
\xydef@\vfromabsolute@@#1,#2@{\X@c=#1\relax
 \DN@{#2}\ifx\next@\empty \Y@c=\X@c
 \else \DN@##1,{\Y@c=##1}\next@#2\relax \fi
 \advance\X@c 1sp \advance\Y@c 1sp
}
\xydef@\cfromthec@{\X@c=\the\X@c \Y@c=\the\Y@c
 \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c
 \Edge@c={\expandafter\noexpand\the\Edge@c}}
\xydef@\cfromthep@{\X@c=\the\X@p \Y@c=\the\Y@p
 \U@c=\the\U@p \D@c=\the\D@p \L@c=\the\L@p \R@c=\the\R@p
 \Edge@c={\expandafter\noexpand\the\Edge@p}}
\xydef@\pfromthep@{\X@p=\the\X@p \Y@p=\the\Y@p
 \U@p=\the\U@p \D@p=\the\D@p \L@p=\the\L@p \R@p=\the\R@p
 \Edge@p={\expandafter\noexpand\the\Edge@p}}
\xydef@\pfromthec@{\X@p=\the\X@c \Y@p=\the\Y@c
 \U@p=\the\U@c \D@p=\the\D@c \L@p=\the\L@c \R@p=\the\R@c
 \Edge@p={\expandafter\noexpand\the\Edge@c}}
\xydef@\cplusthec@{\advance\X@c\the\X@c \advance\Y@c\the\Y@c}
\xydef@\cskewthec@{%
 \noexpand\cskew@{\the\Y@c}{\the\X@c}{\the\D@c}{\the\U@c}{\the\L@c}{\the\R@c}}
\xydef@\cskew@#1#2#3#4#5#6{%
 \D@c=#3\advance\D@c \Y@c \ifdim\D@c<\z@ \D@c=\z@ \fi
 \U@c=#4\advance\U@c-\Y@c \ifdim\U@c<\z@ \U@c=\z@ \fi
 \advance\Y@c#1%
 \L@c=#5\advance\L@c \X@c \ifdim\L@c<\z@ \L@c=\z@ \fi
 \R@c=#6\advance\R@c-\X@c \ifdim\R@c<\z@ \R@c=\z@ \fi
 \advance\X@c#2%
 \Edge@c={\rectangleEdge}}
\xydef@\cmergethec@{%
 \noexpand\cmerge@{\the\Y@c}{\the\X@c}{\the\D@c}{\the\U@c}{\the\L@c}{\the\R@c}}
\xydef@\cmerge@#1#2#3#4#5#6{\the\Edge@c4%
 \A@=#2\advance\A@-\X@c \B@=#1\advance\B@-\Y@c
 \dimen@=#5\advance\L@c \A@ \ifdim\L@c<\dimen@ \L@c=\dimen@ \fi
 \dimen@=#6\advance\R@c-\A@ \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
 \dimen@=#3\advance\D@c \B@ \ifdim\D@c<\dimen@ \D@c=\dimen@ \fi
 \dimen@=#4\advance\U@c-\B@ \ifdim\U@c<\dimen@ \U@c=\dimen@ \fi
 \advance\X@c\A@ \advance\Y@c\B@}
\xydef@\halfroottwo{.70710678}
\xydef@\partroottwo{.29289322}
\xydef@\halfrootthree{.8660254}
\xydef@\vfromcartesian@#1{\vfromcartesian@@#1@}
\xydef@\vfromcartesian@@#1,#2@{%
 \X@c=\X@origin \advance\X@c#1\X@xbase \advance\X@c#2\X@ybase
 \Y@c=\Y@origin \advance\Y@c#1\Y@xbase \advance\Y@c#2\Y@ybase}
\xydef@\setbase@#1#2#3#4{%
 \X@origin=#1\relax \Y@origin=#2\relax
 \X@xbase=#3\relax \advance\X@xbase-\X@origin
 \Y@xbase=#4\relax \advance\Y@xbase-\Y@origin
 \X@ybase=-\Y@xbase \Y@ybase=\X@xbase}
\xydef@\setbase@@#1#2{%
 \X@ybase=#1\relax \advance\X@ybase-\X@origin
 \Y@ybase=#2\relax \advance\Y@ybase-\Y@origin}
\xydef@\basefromthebase@{\X@origin=\the\X@origin \Y@origin=\the\Y@origin
 \X@xbase=\the\X@xbase \Y@xbase=\the\Y@xbase
 \X@ybase=\the\X@ybase \Y@ybase=\the\Y@ybase}
\xydef@\vfromcartesianangle@#1{\enter@\basefromthebase@ \R@=#1\p@
 \B@=360\p@
 \loop@ \ifdim\R@<\z@ \advance\R@\B@ \repeat@
 \loop@ \ifdim\R@>\B@ \advance\R@-\B@ \repeat@
 \ifdim\R@<.5\B@\else \R@=-\R@ \advance\R@\B@
 \X@ybase=-\X@ybase \Y@ybase=-\Y@ybase \fi
 \B@=180\p@
 \ifdim\R@<.5\B@\else \R@=-\R@ \advance\R@\B@
 \X@xbase=-\X@xbase \Y@xbase=-\Y@xbase \fi
 \B@=90\p@
 \ifdim\R@<.5\B@ \let\nextiii@=\literal@
 \else \R@=-\R@ \advance\R@\B@ \def\nextiii@##1,##2@{##2,##1@}\fi
 \dimen@=\z@ \DN@{1,0@}%
 \dimen@ii=45\p@ \DNii@{.70710678,.70710678@}%
 \chooseangleinterval@
 {\chooseangleinterval@
 {\chooseangleinterval@
 {\chooseangleinterval@
 {\chooseangleinterval@
 {}%
 {4.090909}{.99677570,.08023846@}%
 {}}%
 {6}{.99452190,.10452846@}%
 {\chooseangleinterval@
 {}%
 {8.181818}{.98982144,.14231484@}%
 {}}}%
 {10}{.98480775,.17364818@}%
 {\chooseangleinterval@
 {}%
 {12.857143}{.97492791,.22252093@}%
 {}}}%
 {15}{.96592583,.25881905@}%
 {\chooseangleinterval@
 {\chooseangleinterval@
 {}%
 {16.363636}{.95949297,.28173256@}%
 {}}%
 {18}{.95105652,.30901699@}%
 {\chooseangleinterval@
 {}%
 {20}{.93969262,.34202014@}%
 {}}}}%
 {22.5}{.92387953,.38268343@}%
 {\chooseangleinterval@
 {\chooseangleinterval@
 {\chooseangleinterval@
 {}%
 {24.545455}{.90963200,.41541501@}%
 {}}%
 {25.714286}{.90096887,.43388374@}%
 {}}%
 {30}{.86602540,.5@}%
 {\chooseangleinterval@
 {\chooseangleinterval@
 {}%
 {32.727273}{.84125353,.54064082@}%
 {}}%
 {36}{.80901699,.58778525@}%
 {\chooseangleinterval@
 {\chooseangleinterval@
 {}%
 {38.571429}{.78183148,.62348980@}%
 {}}%
 {40.909091}{.75574957,.65486073@}%
 {\chooseangleinterval@
 {}%
 {40}{.76604444,.64278761@}%
 {}}}}}%
 \A@=\R@ \advance\A@-\dimen@
 \ifdim\ifdim\A@<\z@-\fi\A@<.01\p@ \edef\next@{\expandafter\nextiii@\next@}%
 \else \B@=\dimen@ii \advance\B@-\R@ 
 \ifdim\A@<\B@ \dimen@=\toradians@\A@
 \edef\next@{\next@ \expandafter\removePT@\the\dimen@ @}%
 \else \dimen@=-\toradians@\B@
 \edef\next@{\nextii@ \expandafter\removePT@\the\dimen@ @}%
 \fi
 \expandafter\interpolatepoint@\next@
 \edef\next@{\expandafter\nextiii@\next@}%
 \fi 
 \expandafter\vfromcartesian@@\next@
 \leave@}
\xydef@\chooseangleinterval@#1#2#3#4{%
 \B@=#2\p@ \def\next{#3}%
 \ifdim\R@<\B@ \dimen@ii=\B@ \let\nextii@=\next #1%
 \else \dimen@=\B@ \let\next@=\next \ifdim\B@<\R@ #4\fi\fi}
\xydef@\interpolateinterval@#1,#2@#3,#4@{%
 \A@=#1\p@ \dimen@=#3\p@ \advance\dimen@-\A@ \advance\A@\next\dimen@
 \B@=#2\p@ \dimen@=#4\p@ \advance\dimen@-\B@ \advance\B@\next\dimen@
 \edef\next@{\expandafter\removePT@\the\A@,\expandafter\removePT@\the\B@ @}}
\xydef@\toradians@{0.01745329}
\xydef@\interpolatepoint@#1,#2@#3@{%
 \A@=#1\p@ \dimen@ii=#3\A@ \dimen@ii=-.5\dimen@ii \advance\A@#3\dimen@ii
 \dimen@=-#2\p@ \advance\A@#3\dimen@
 \B@=#2\p@ \dimen@ii=#3\B@ \dimen@ii=-.5\dimen@ii \advance\B@#3\dimen@ii
 \dimen@=#1\p@ \advance\B@#3\dimen@
 \edef\next@{\expandafter\removePT@\the\A@,\expandafter\removePT@\the\B@ @}}
\xydef@\drop@#1#2{%
 \global\setbox\lastobjectbox@=\object#1{#2}%
 \ifHidden@ \dimen@=\X@c \advance\dimen@-\L@c \else
 \dimen@=\Y@c \advance\dimen@ \U@c \ifdim\Y@max<\dimen@ \Y@max=\dimen@ \fi
 \dimen@=\Y@c \advance\dimen@-\D@c \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi
 \dimen@=\X@c \advance\dimen@ \R@c \ifdim\X@max<\dimen@ \X@max=\dimen@ \fi
 \dimen@=\X@c \advance\dimen@-\L@c \ifdim\dimen@<\X@min \X@min=\dimen@ \fi \fi
 \ifInvisible@\else
 \setboxz@h{\kern\dimen@ \raise\Y@c\box\lastobjectbox@}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ {\Drop@@}\fi}
\xydef@\connect@#1#2{\setupDirection@ \enter@{\cfromthec@}%
 \global\setbox\lastobjectbox@=\object#1{#2}\leave@
 \Connect@@}
\xydef@\afterPLACE#1{%
 \DN@##1{\def\afterPLACE@{\xy@@\leave@ \def\afterPLACE@{##1}#1}}%
 \expandafter\next@\expandafter{\afterPLACE@}%
 \def\PLACEf@{{.5}}%
 \xy@@{\enter@{\pfromthep@}%
 \Creset@@
 \def\PLACEf@{{.5}}%
 \let\PLACEedgep@@=\PLACEedgep@ \let\PLACEedgec@@=\PLACEedgec@}%
 \xyFN@\PLACE@}
\xydef@\PLACEf@{}
\xydef@\PLACEedgep@@{}
\xydef@\PLACEedgec@@{}
\xydef@\PLACEedgep@{\Cshavep@@ \def\PLACEedgep@@{\Cslidep@@\jot}}
\xydef@\PLACEedgec@{\Cshavec@@ \def\PLACEedgec@@{\Cslidec@@{-\jot}}}
\xylet@\afterPLACE@=\empty
\xydef@\PLACE@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@}%
 \else\addLT@\ifx \next
 \addLT@\DN@{\addLT@\xy@{\def\PLACEf@{{0}}\PLACEedgep@@}\xyFN@\PLACE@}%
 \else\addGT@\ifx \next
 \addGT@\DN@{\addGT@\xy@{\def\PLACEf@{{1}}\PLACEedgec@@}\xyFN@\PLACE@}%
 \else\ifx (\next
 \DN@(##1){\def\PLACEf@{{##1}}\xy@{(##1)}{\def\PLACEf@{{##1}}}\xyFN@\PLACE@}%
 \else\ifx !\next
 \DN@!{\xyFN@\PLACE@intercept}%
 \else
 \DN@{\xy@@{\expandafter\Calong@@\PLACEf@ \czeroEdge@}\PLACE@@}%
 \fi\fi\fi\fi\fi \next@}
\xydef@\PLACE@intercept{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@intercept}%
 \else\ifx \bgroup\next
 \DN@##1{\xy@{!{##1}}{}\PLACE@intercept@{##1}}%
 \else\ifx (\next
 \DN@(*##1*){\xy@{!(*##1*)}{}\PLACE@intercept@{##1}}%
 \else \DN@{\xyerror@{{<pos>} expected after ! in <place>}{}}%
 \fi\fi\fi \next@}
\xydef@\PLACE@intercept@#1{%
 \xy@@{\enter@{\pfromthep@\basefromthebase@}\begingroup}%
 \xy@@ix@{#1}\xy@@{\plainxy@ \expandafter\POS\the\toks9\relax
 \edef\next@{\endgroup
 \X@c =\the\X@c \Y@c=\the\Y@c \X@p=\the\X@p \Y@p=\the\Y@p}%
 \next@ \Cintercept@@ \leave@}%
 \PLACE@@}
\xydef@\PLACE@@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@@}%
 \else\ifx /\next \DN@/##1/{\xy@{/##1/}{\Cslidec@@{##1}}\afterPLACE@}%
 \else \let\next@=\afterPLACE@
 \fi\fi \next@}
\xydef@\intersect@{%
 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p
 \A@=\X@c \advance\A@-\X@origin \B@=\Y@c \advance\B@-\Y@origin
 \edef\next@{\expandafter\removePT@\the\R@c}%
 \edef\nextii@{\expandafter\removePT@\the\U@c}%
 \D@c=\next@\d@Y \advance\D@c-\nextii@\d@X \divide\D@c\KK@
 \L@c=\next@\B@ \advance\L@c-\nextii@\A@ \divide\L@c\KK@
 \ifdim\D@c=\z@\zeroDivide@\else \quotient@\next@\L@c\D@c \fi
 \advance\X@c-\next@\d@X \advance\Y@c-\next@\d@Y
 \czeroEdge@}
\xydef@\zeroDivide@@{\zeroDivide@message{\intersect@}{treated as 0}\DN@{0}}
\xydef@\zeroDivide@message#1#2{\xywarning@{division by 0 in \string#1, #2}}
\xylet@\zeroDivide@=\zeroDivide@@
\xydef@\zeroDivideLimit@@{\ifdim\L@c=\z@ \DN@{0}%
 \else\ifdim\L@c<\z@\DN@{-\zeroDivide@Limit}%
 \else\DN@{\zeroDivide@Limit}\fi\fi
 \zeroDivide@message{\intersect@}{replaced by \zeroDivide@Limit}}
\xydef@\zeroDivideLimit@#1{\edef\zeroDivide@Limit{#1}%
 \let\zeroDivide@=\zeroDivideLimit@@}
\xylet@\zeroDivideLimit=\zeroDivideLimit@
\xydef@\vfromslide@#1{\enter@\DirectionfromtheDirection@ \begingroup
 \plainxy@\afterDIRECTIONorEMPTY\vfromslide@i\vfromslide@i#1@}
\xydef@\vfromslide@i#1@{\DN@{#1}%
 \edef\next{\endgroup
 \ifx\next@\empty \dimen@=.5pc \else \dimen@=#1\relax \fi
 \X@c=\cosDirection\dimen@ \Y@c=\sinDirection\dimen@}\next
 \leave@}
\xydef@\s@bot{-1}
\xydef@\s@top{-1}
\xydef@\cfroms@#1{\tests@{#1}\runs@\outofranges@}
\xydef@\tests@#1#2#3{\DN@{#3}%
 \count@=\s@top \advance\count@-#1\relax
 \ifnum\count@>\s@bot\relax \ifnum\count@>\s@top\else\DN@{#2}\fi\fi
 \next@}
\xydef@\runs@{\csname S@\the\count@\endcsname}
\xydef@\outofranges@{\count@=\s@top \advance\count@-\s@bot
 \xyerror@{stack index out of range (should be 0..\the\count@)}{}}
\xydef@\STACK@{%
 \addPLUS@\ifx\next
 \addPLUS@\DN@{\xy@{@+}{}\afterCOORD{\xy@@\spushc@ \xyFN@\POS@}}%
 \else\addDASH@\ifx\next
 \addDASH@\DN@{\xy@{@-}{}\afterCOORD{\xy@@\spop@ \xyFN@\POS@}}%
 \else \ifx i\next \DN@ i{\xy@{@i}\sinit@ \xyFN@\POS@}%
 \else \ifx (\next \DN@ ({\xy@{@(}\senter@ \xyFN@\POS@}%
 \else \ifx )\next \DN@ ){\xy@{@)}\sleave@ \xyFN@\POS@}%
 \else\addEQ@\ifx\next \addEQ@\DN@{\STACK@load}%
 \else\addAT@\ifx\next \addAT@\DN@{\xy@{@@}{}\smap@}%
 \else \DN@##1{\xyerror@{illegal stack command ##1}{}\afterCOORD{\xyFN@\POS@}}%
 \fi\fi\fi\fi\fi\fi\fi \next@}
\xydef@\STACK@load{\xy@{@=}{%
 \if\sempty@\else \xywarning@{loading on top of non-empty stack}\sinit@ \fi
 \let\comma@@=\spushc@}%
 \afterCOORD{\xy@@{\spushc@ \let\comma@@=\relax}\xyFN@\POS@}}
\xydef@\spushc@{%
 \count@=\s@top \advance\count@\@ne \edef\s@top{\the\count@}%
 \expandafter\edef\csname S@\s@top\endcsname{\cfromthec@}}
\xydef@\spushid@#1{\DNii@{#1}\edef\nextii@{\codeof\nextii@}%
 \expandafter\let\expandafter\next@\csname Q@\nextii@\endcsname
 \ifx\next@\relax \xyerror@{<pos> \string"\nextii@\string" not defined}{}%
 \else
 \count@=\s@top \advance\count@\@ne \edef\s@top{\the\count@}%
 \DNii@##1{\expandafter\def\csname S@\s@top\endcsname{##1}}%
 \expandafter\nextii@\expandafter{\next@}%
 \fi}
\xydef@\idfroms@#1#2{%
 \tests@{#2}{\DN@{\idfromxy@{#1}}%
 \expandafter\expandafter\expandafter\next@
 \expandafter\expandafter\expandafter{\csname S@\the\count@\endcsname}%
 }\outofranges@}
\xydef@\spop@{\count@=\s@top
 \ifnum\count@>\s@bot \advance\count@\m@ne \edef\s@top{\the\count@}%
 \else \xyerror@{nothing to pop from stack}{}\fi}
\xydef@\sinit@{\edef\s@top{\s@bot}}
\xydef@\senter@{%
 \count@=\s@top \advance\count@\@ne
 \expandafter\edef\csname S@\the\count@\endcsname{\s@bot}%
 \edef\s@bot{\the\count@}\edef\s@top{\the\count@}}
\xydef@\sleave@{%
 \ifnum\s@bot=\s@top\else \xywarning@{leaving non-empty stack}\sinit@ \fi
 \ifnum\s@bot>\m@ne \edef\s@bot{\csname S@\s@top\endcsname}%
 \count@=\s@top \advance\count@\m@ne \edef\s@top{\the\count@}%
 \edef\sbot{\the\count@}\fi}
\xydef@\sempty@{\ifnum\s@top=\s@bot TT\else TF\fi}
\xydef@\xytotoks@#1#2{\addtotoks@{#2}}
\xydef@\xytotoks@@toksix@#1{\addtotoks@{\toks9={#1}}}
\xydef@\smap@{%
 \begingroup \toks@={}\let\xy@=\xytotoks@ \let\oxy@=\xy@
 \let\xy@@ix@=\xytotoks@@toksix@
 \afterCOORD{\expandafter\endgroup
 \expandafter\smapxy@@\expandafter{\the\toks@}\xyFN@\POS@}}
\xydef@\smapxy@@#1{\xy@@{\edef\smapp@@{\s@bot}\smapxy@i{#1}}}
\xylet@\smapp@@=\empty
\xydef@\smapxy@i#1{%
 \ifnum\smapp@@<\s@top
 \count@=\smapp@@ \advance\count@\@ne \edef\smapp@@{\the\count@}%
 \DN@{\csname S@\smapp@@\endcsname #1\relax \smapxy@i{#1}}%
 \else \let\next@=\relax
 \fi \next@}
\xydef@\saveid@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\saveid@}%
 \else \ifx "\next\DN@"##1"{\xy@{="##1"}{\idfromc@{##1}}\xyFN@\POS@}%
 \else \ifx :\next\DN@:##1"##2"{\xy@{=:"##2"}{\idfrombase@{##2}}\xyFN@\POS@}%
 \else\addAT@\ifx\next
 \addAT@\DN@"##1"{\xy@{=@"##1"}{\idfromstack@{##1}}\xyFN@\POS@}%
 \else \ifx s\next
 \DN@ s##1"##2"{\xy@{=s##1"##2"}{\idfroms@{##2}{##1}}\xyFN@\POS@}%
 \else\addEQ@\ifx\next \let\saveid@COORD@@=\saveid@COORDii
 \addEQ@\DN@{\xyFN@\saveid@COORD}%
 \else \let\saveid@COORD@@=\saveid@COORDi \let\next@=\saveid@COORD
 \fi\fi\fi\fi\fi\fi \next@}
\xylet@\saveid@COORD@@=\relax
\xydef@\idfromc@#1{\DN@{#1}%
 \expandafter\edef\csname Q@\codeof\next@\endcsname{\cfromthec@}}
\xydef@\idfrombase@#1{\DN@{#1}%
 \expandafter\edef\csname Q@\codeof\next@\endcsname{\basefromthebase@}}
\xydef@\idfromstack@#1{%
 \toks@={\if\sempty@\else
 \xywarning@{loading on top of non-empty stack}\sinit@ \fi}%
 \count@=\s@bot \advance\count@\@ne
 \ifnum\count@>\s@top\else
 \loop@
 \expandafter\let\expandafter\next@\csname S@\the\count@\endcsname
 \expandafter\addtotoks@\expandafter{\next@}%
 \ifnum\count@<\s@top \advance\count@\@ne \addtotoks@{\spushc@}\repeat@
 \fi
 \DN@{#1}\edef\next@##1{%
 \def\expandafter\noexpand\csname Q@\codeof\next@\endcsname{##1}}%
 \expandafter\next@\expandafter{\the\toks@}}
\xydef@\saveid@COORD{%
 \begingroup \toks@={}\let\xy@=\xytotoks@ \let\oxy@=\xy@
 \let\xy@@ix@=\xytotoks@@toksix@
 \afterCOORD{\expandafter\saveid@COORDi\expandafter{\the\toks@}}}
\xydef@\saveid@COORDi#1#2"#3"{\endgroup \xy@@{\idfromxy@{#3}{#1}}\xyFN@\POS@}
\xydef@\saveid@COORDii#1#2"#3"{\endgroup \xy@@{\idfromcxy@{#3}{#1}}\xyFN@\POS@}
\xydef@\idfromxy@#1#2{\DN@{#1}%
 \expandafter\def\csname Q@\codeof\next@\endcsname{#2}}
\xydef@\idfromcxy@#1#2{\DN@{#1}%
 \expandafter\edef\csname Q@\codeof\next@\endcsname{\cfromthec@#2}}
\xydef@\cfromid@#1{\DNii@{#1}\edef\nextii@{\codeof\nextii@}%
 \expandafter\let\expandafter\next@\csname Q@\nextii@\endcsname
 \ifx\next@\relax \xyerror@{<pos> \string"\nextii@\string" not defined}{}%
 \else \expandafter\next@\fi}
\message{objects,}
\xydef@\OBJECT@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\OBJECT@}%
 \else\ifcat A\noexpand\next \let\next@=\OBJECT@letter
 \else \let\next@=\OBJECT@other \fi\fi \next@}
\xydef@\OBJECT@letter{%
 \ifx i\next \DN@ i{\addtotoks@\Invisible@true \xyFN@\OBJECT@}%
 \else\ifx h\next\DN@ h{\addtotoks@\Hidden@true \xyFN@\OBJECT@}%
 \else\ifx o\next\DN@ o{\xywarning@{Obsolete o modifier used}\OBJECT@shape{o}}%
 \else\ifx x\next\DN@ x{\xywarning@{Obsolete x modifier used}\OBJECT@shape{}}%
 \else \let\next@=\OBJECT@direction
 \fi\fi\fi\fi \next@}
\xydef@\OBJECT@other{%
 \ifx !\next \DN@!{\OBJECT@shift}%
 \else\addPLUS@\ifx \next \DN@{\OBJECT@change}%
 \else\addDASH@\ifx \next \DN@{\OBJECT@change}%
 \else\addEQ@\ifx \next \DN@{\OBJECT@set}%
 \else\ifx [\next
 \DN@[##1]{\xy@{[##1]}{\OBJECT@shape{##1}}}%
 \else\ifx ^\next \let\next@=\OBJECT@direction
 \else\ifx _\next \let\next@=\OBJECT@direction
 \else\ifx :\next \let\next@=\OBJECT@direction
 \else\ifx ?\next
 \DN@ ?{\xywarning@{\string? modifier used}\xyFN@\OBJECT@direction}%
 \else\ifx (\next
 \let\next@=\OBJECT@direction
 \else\addAT@\ifx\next \addAT@\DN@##1##{\OBJECT@@{\dir##1}}%
 \else \DN@##1##{\OBJECT@@{##1}}%
 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xydef@\prevEdge@@{\zeroEdge}
\xydef@\OBJECT@@#1#2{%
 \expandafter\def\expandafter\prevEdge@@\expandafter{\the\Edge@c}%
 \expandafter\Edge@c\expandafter{\objectEdge}%
 \Invisible@false\Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\boxz@}\def\Connect@@{\straight@\relax}%
 \DN@{#1}\ifx\next@\empty \DNii@{#2}%
 \ifx\nextii@\empty \DN@{\hbox\bgroup\no@}\else \let\next@=\objectbox \fi\fi
 \setbox\z@=\next@{#2}\L@c=\Leftness@\wdz@ \R@c=\wdz@ \advance\R@c-\L@c
 \D@c=\dp\z@ \advance\D@c\ht\z@ \U@c=\Upness@\D@c \advance\D@c-\U@c
 \R@p=\z@ \L@p=\L@c \U@p=\U@c \advance\U@p-\ht\z@ \D@p=-\U@p
 \the\toks@\toks@={}\setboxz@h{\kern\R@p \raise\U@p\boxz@}%
 \checkZeroEdge@
 \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@ \ht\z@=\U@c \dp\z@=\D@c \boxz@
 \OBJECT@x}
\xydef@\adjustLR@{%
 \ifdim\zz@\wdz@ \L@c=\z@ \R@c=\z@ \dimen@=\Leftness@\p@
 \ifdim\dimen@<\z@ \L@c=\dimen@ \R@c=-\L@c
 \else\ifdim\dimen@>\p@ \L@c=\dimen@ \advance\L@c-\p@ \R@c=-\L@c \fi\fi
 \else \L@c=\Leftness@\wdz@ \R@c=\wdz@ \advance\R@c-\L@c \fi}
\xydef@\adjustUD@{\dimen@=\ht\z@ \advance\dimen@\dp\z@
 \ifdim\zz@\dimen@ \U@c=\z@ \D@c=\z@ \dimen@=\Upness@\p@
 \ifdim\dimen@<\z@ \U@c=\dimen@ \D@c=-\L@c
 \else\ifdim\dimen@>\p@ \U@c=\dimen@ \advance\U@c-\p@ \D@c=-\L@c \fi\fi
 \else \D@c=\dimen@ \U@c=\Upness@\dimen@ \advance\D@c-\U@c \fi}
\xydef@\checkZeroEdge@{%
 \expandafter\DN@\expandafter{\expandafter\noexpand\the\Edge@c}%
 \DNii@{\noexpand\zeroEdge}%
 \ifx\next@\nextii@ \DN@{\expandafter\Edge@c\expandafter{\objectEdge}}%
 \ifdim\zz@\L@c \ifdim\zz@\R@c \ifdim\zz@\U@c \ifdim\zz@\D@c
 \DN@{}\fi\fi\fi\fi
 \else
 \ifdim\zz@\L@c \ifdim\zz@\R@c \ifdim\zz@\U@c \ifdim\zz@\D@c
 \DN@{\Edge@c={\zeroEdge}}\fi\fi\fi\fi
 \fi \next@}
\xydef@\OBJECT@x{\toks@={\egroup\def\Drop@@}%
 \expandafter\addtotoks@\expandafter{\expandafter{\Drop@@}\def\Connect@@}%
 \expandafter\addtotoks@\expandafter{\expandafter{\Connect@@}}%
 \edef\tmp@{\D@c=\the\D@c \U@c=\the\U@c \L@c=\the\L@c \R@c=\the\R@c
 \Edge@c={\expandafter\noexpand\the\Edge@c}%
 \ifInvisible@\noexpand\Invisible@true\else\noexpand\Invisible@false\fi
 \ifHidden@\noexpand\Hidden@true\else\noexpand\Hidden@false\fi
 \def\noexpand\Leftness@{\Leftness@}\def\noexpand\Upness@{\Upness@}}%
 \expandafter\addtotoks@\expandafter{\tmp@}\the\toks@}
\xynew@{if}\ifInvisible@
\xynew@{if}\ifHidden@
\xydef@\Leftness@{}
\xydef@\Upness@{}
\xydef@\Drop@@{\boxz@}
\xydef@\Connect@@{}
\xydef@\objectbox#1{\hbox{$\m@th\objectstyle{#1}$}}
\xylet@\objectstyle=\textstyle
\xydef@\object{\hbox\bgroup\object@}
\xydef@\object@{%
 \edef\next@{={\DirectionfromtheDirection@}}\expandafter\toks@\next@
 \plainxy@ \xyFN@\OBJECT@}
\xydef@\composite#1#{\hbox\bgroup\composite@{#1}}
\xydef@\composite@#1#2{%
 \DN@{#1}\ifx\next@\empty\else\xywarning@{no variants of
 \string\composite\space allowed}\fi
 \global\setbox9=\hbox\bgroup
 \D@p=-\maxdimen \U@p=-\maxdimen \L@p=-\maxdimen \R@p=-\maxdimen
 \xyFN@\composite@i#2@}
\xydef@\composite@i{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\composite@i}%
 \else\ifx *\next \DN@ *{\xyFN@\composite@i}%
 \else\ifx @\next \DN@ @{\composite@x}%
 \xyerror@{<composite> object expected}{}\czeroEdge@
 \else \DN@{\composite@ii}\fi\fi\fi \next@}
\xydef@\composite@ii#1#{\composite@iii{#1}}
\xydef@\composite@iii#1#2{%
 \setbox\z@=\object#1{#2}%
 \ifInvisible@ \setboxz@h{}%
 \else \setboxz@h{\kern-\L@c \boxz@}\ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ {\Drop@@}\fi
 \ifHidden@\else
 \ifdim\U@p<\U@c \U@p=\U@c \fi \ifdim\D@p<\D@c \D@p=\D@c \fi
 \ifdim\R@p<\R@c \R@p=\R@c \fi \ifdim\L@p<\L@c \L@p=\L@c \fi
 \fi
 \xyFN@\composite@iv}
\xydef@\composite@iv{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\composite@iv}%
 \else \ifx @\next \DN@ @{\composite@x}%
 \else \let\next@=\composite@i \fi\fi \next@}
\xydef@\composite@x{%
 \edef\tmp@{\egroup \D@c=\the\D@p \U@c=\the\U@p \L@c=\the\L@p \R@c=\the\R@p}\tmp@
 \setboxz@h{\kern\L@c\box9}\ht\z@=\U@c \dp\z@=\D@c
 \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@
 \Edge@c={\rectangleEdge}\computeLeftUpness@ \boxz@
 \OBJECT@x}
\xydef@\computeLeftUpness@{%
 \dimen@=\L@c \advance\dimen@\R@c
 \ifdim\zz@\dimen@ \def\Connect@@{\straight@{\dottedSpread@\jot}}%
 \ifdim\zz@\L@c\else
 \DN@{\zeroEdge}\expandafter\DNii@\expandafter{\the\Edge@c}%
 \ifx\next@\nextii@\Edge@c={\rectangleEdge}\fi\fi
 \else \quotient@\Leftness@\L@c\dimen@ \fi
 \dimen@=\U@c \advance\dimen@\D@c 
 \ifdim\zz@\dimen@ \def\Connect@@{\straight@{\dottedSpread@\jot}}%
 \ifdim\zz@\U@c\else
 \DN@{\zeroEdge}\expandafter\DNii@\expandafter{\the\Edge@c}%
 \ifx\next@\nextii@\Edge@c={\rectangleEdge}\fi\fi
 \else \quotient@\Upness@\U@c\dimen@ \fi}
\xydef@\xybox#1{\xy#1\endxy \Edge@c={\rectangleEdge}\computeLeftUpness@}
\xydef@\OBJECT@shift{%
 \let\xy@=\xytotoks@ \afterVECTORorEMPTY
 {\OBJECT@shift@}%
 {\addtotoks@{\X@c=-\L@c \advance\X@c\R@p \advance\X@c\L@p \Y@c=\U@p}\OBJECT@shift@}}
\xydef@\OBJECT@shift@{%
 \addtotoks@{\advance\U@p-\Y@c
 \advance\L@c\X@c \advance\R@c-\X@c \advance\D@c\Y@c \advance\U@c-\Y@c
 \computeLeftUpness@}%
 \let\xy@=\oxy@
 \xyFN@\OBJECT@}
\xylet@\objectmargin@=\jot
\xylet@\objectwidth@=\z@
\xylet@\objectheight@=\z@
\xydef@\objectmargin{\afterADDOP{\Addop@@\objectmargin@}}
\xydef@\objectwidth{\afterADDOP{\Addop@@\objectwidth@}}
\xydef@\objectheight{\afterADDOP{\Addop@@\objectheight@}}
\xydef@\OBJECT@change{%
 \afterADDOP{%
 \addEQ@\ifx \next
 \addtotoks@{\X@c=\D@c \advance\X@c\U@c \Y@c=\L@c \advance\Y@c\R@c}%
 \else
 \addtotoks@{\X@c=\objectmargin@ \advance\X@c\X@c \Y@c=\X@c}%
 \fi
 \let\xy@=\xytotoks@ 
 \afterVECTORorEMPTY\OBJECT@change@\OBJECT@change@}}
\xydef@\OBJECT@set{%
 \afterADDOP{%
 \let\xy@=\xytotoks@ \afterVECTORorEMPTY\OBJECT@change@
 {\addtotoks@{\X@c=\objectwidth@ \Y@c=\objectheight@}\OBJECT@change@}}}
\xydef@\OBJECT@change@{%
 \addtotoks@{\advance\R@c\L@c \advance\R@p-\L@c \let\tmp@=\R@c}%
 \expandafter\addtotoks@\expandafter{\Addop@@\tmp@\X@c\R@c=\tmp@
 \L@c=\Leftness@\R@c \advance\R@p\L@c \advance\R@c-\L@c}%
 \addtotoks@{\advance\D@c\U@c \let\tmp@=\D@c}%
 \expandafter\addtotoks@\expandafter{\Addop@@\tmp@\Y@c\D@c=\tmp@
 \U@c=\Upness@\D@c \advance\D@c-\U@c}%
 \let\xy@=\oxy@ \xyFN@\OBJECT@}
\xydef@\afterADDOP#1{\def\afterADDOP@{#1}\xyFN@\ADDOP@}
\xylet@\afterADDOP@=\empty
\xydef@\ADDOP@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\ADDOP@}%
 \else\addPLUS@\ifx \next \addPLUS@\DN@{\xyFN@\ADDOP@plus}%
 \else\addDASH@\ifx \next \addDASH@\DN@{\xyFN@\ADDOP@minus}%
 \else\addEQ@\ifx \next
 \addEQ@\DN@{\def\Addop@@{\Addop@0+=}\afterADDOP@}%
 \else
 \DN@{\def\Addop@@{\Addop@0+=}\afterADDOP@}%
 \fi\fi\fi\fi \next@}
\xydef@\ADDOP@plus{%
 \addEQ@\ifx \next
 \addEQ@\DN@{\def\Addop@@{\Addop@0+<}\afterADDOP@}%
 \else
 \DN@{\def\Addop@@{\Addop@1+=}\afterADDOP@}%
 \fi \next@}
\xydef@\ADDOP@minus{%
 \addEQ@\ifx \next
 \addEQ@\DN@{\def\Addop@@{\Addop@0+>}\afterADDOP@}%
 \else
 \DN@{\def\Addop@@{\Addop@1-=}\afterADDOP@}%
 \fi \next@}
\xydef@\Addop@#1#2#3#4#5{%
 \dimen@=#4\relax \edef#4{\the\dimen@}%
 \dimen@=#1\dimen@ \advance\dimen@#2#5\relax \advance\dimen@ 1sp
 \ifdim\dimen@#3#4\else \edef#4{\the\dimen@}\fi
 \ifx\xy@\xyinitial@\else \DN@##1{\xy@@{\edef#4{##1}\checkZeroEdge@}}%
 \expandafter\next@\expandafter{#4}\fi}
\xydef@\objectEdge{\rectangleEdge}
\xydefcsname@{shape [r]}{%
 \advance\R@c\L@c \L@c=.5\U@c \advance\L@c.5\D@c \advance\R@c-\L@c}
\xydefcsname@{shape [l]}{%
 \advance\L@c\R@c \R@c=.5\U@c \advance\R@c.5\D@c \advance\L@c-\R@c}
\xydefcsname@{shape [u]}{%
 \advance\U@c\D@c \D@c=.5\L@c \advance\D@c.5\R@c \advance\U@c-\D@c}
\xydefcsname@{shape [d]}{%
 \advance\D@c\U@c \U@c=.5\L@c \advance\U@c.5\R@c \advance\D@c-\U@c}
\xydefcsname@{shape [c]}{%
 \advance\D@c\U@c \D@c=.5\D@c \U@c=\D@c \advance\L@c\R@c \L@c=.5\L@c \R@c=\L@c}
\xydef@\OBJECT@shape#1{\DN@{shape [#1]}%
 \expandafter\let\expandafter\nextii@\csname\codeof\next@\endcsname
 \ifx\nextii@\relax\DN@{style [#1]}%
 \expandafter\let\expandafter\nextii@\csname\codeof\next@\endcsname
 \ifx\nextii@\relax \DN@{\OBJECT@shapei[#1]}%
 \else\DN@{\nextii@\xyFN@\OBJECT@}\fi
 \else \expandafter\addtotoks@\expandafter{\nextii@}%
 \DN@{\xyFN@\OBJECT@}%
 \fi \next@}
\xydefcsname@{shape []}{\the\Edge@c5\relax}%
\xydefcsname@{shape [o]}{\Edge@c={\circleEdge}\the\Edge@c5\relax 
 \Edge@c={\circleEdge}\def\prevEdge@@{\circleEdge}}
\xydefcsname@{shape [.]}{\czeroEdge@}
\xydef@\OBJECT@shapei[#1#2]{\DN@{shape [#1...]}%
 \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
 \ifx\next\relax\DN@{*stylechar@#1@}%
 \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
 \ifx\next\relax\DNii@{shape [#1#2]}%
 \xywarning@{illegal [<shape>] ignored: \codeof\nextii@\space not defined}%
 \DN@{\xyFN@\OBJECT@}\else \DN@{\next{#2}\xyFN@\OBJECT@}\fi
 \else
 \expandafter\addtotoks@\expandafter{\next{#2}}\DN@{\xyFN@\OBJECT@}%
 \fi \next@}
\xywarnifdefined\preXY@style@
\xywarnifdefined\postXY@style@
 \gdef\preXY@style@{}
 \gdef\postXY@style@{}
\xydef@\xy@style@{}
\xydef@\preStyle@@{}
\xydef@\postStyle@@{}
\xydef@\xypre@Style@{\let\xypost@Style@=\xypost@Style@@}
\xydef@\xypost@Style@{\let\xypre@Style@=\xypre@Style@@}
\xydef@\xypre@skipStyle@#1\xypost@Style@@{#1}
\xydef@\xypre@Style@@{\styletoks@={}\preXY@style@
 \expandafter\DN@\expandafter{\the\styletoks@}%
 \ifx\next@\empty \DN@{\let\xypre@Style@=\relax \xypre@skipStyle@}%
 \else
 \let\xypre@Style@=\relax \let\xypost@Style@=\xypost@Style@@
 \DN@{\expandafter\xydoprestyles@\expandafter{\the\styletoks@}}%
 \fi \next@ }
\xydef@\xypost@Style@@{\styletoks@={}\postXY@style@
 \expandafter\xydopoststyles@\expandafter{\the\styletoks@}%
 \let\xypost@Style@=\relax \let\xypre@Style@=\xypre@Style@@ }
\xydef@\xydoprestyles@@{\literal@}
\xydef@\xydopoststyles@@{\literal@}
\xylet@\xydoprestyles@=\xydoprestyles@@
\xylet@\xydopoststyles@=\xydopoststyles@@
\xydef@\loadxystyle@{\let\xypre@Style@=\xypre@Style@@}\loadxystyle@
\xydef@\preXYstyle@@{}
\xydef@\postXYstyle@@{}
\xydef@\Unloadstyle@{%
 \let\preXYstyle@=\preXYstyle@@
 \let\postXYstyle@=\postXYstyle@@}
\xydef@\checkXyStyle@{\ifx\xy@style@\empty\resetStyle@
 \ifInvisible@\else\ifHidden@\else\DN@{\no@@}\ifx\next@\Connect@@
 \else\styleDrop@\styleConnect@\fi\fi\fi\fi}
\xydef@\resetStyle@{\gdef\preXY@style@{}\gdef\postXY@style@{}}
\xydef@\styleDrop@{\let\xy@style@=\relax
 \expandafter\def\expandafter\Drop@@\expandafter{%
 \expandafter\xypre@Style@@\Drop@@\xypost@Style@@}}
\xydef@\styleConnect@{\let\xy@style@=\relax
 \expandafter\def\expandafter\Connect@@\expandafter{%
 \expandafter\xypre@Style@@\Connect@@\xypost@Style@@}}
\xydefcsname@{shape [=...]}#1{\checkXyStyle@ \addtotoks@{\xynamestyle@{#1}}}
\xydef@\xynamestyle@#1{\checkXyStyle@
 \expandafter\DNii@\expandafter{\csname shape [#1]\endcsname}%
 \expandafter\ifx\nextii@\relax\xywarning@{Defining new style [#1]}%
 \else\xywarning@{Redefining style [#1]}\fi
 \expandafter\xynamestyle@@\csname shape [#1]\endcsname }
\xydef@\xynamestyle@@#1{%
 \expandafter\def\expandafter\tmp@\expandafter{\preXY@style@}%
 \DN@##1{\def\tmp@{\checkXyStyle@\gdef\preXY@style@{##1}}}%
 \expandafter\next@\expandafter{\preXY@style@}%
 \DN@##1{\expandafter\gdef\expandafter#1\expandafter{\tmp@
 \gdef\postXY@style@{##1}}}%
 \expandafter\next@\expandafter{\postXY@style@}\DN@{}}
\xydef@\newxystyle#1#2#3{%
 \DN@{#3}\ifx\next@\empty 
 \xydefcsname@{shape [#1]}{\csname xyshape@#1@\endcsname}%
 \else \expandafter\def\csname shape [#1]\endcsname{%
 \csname xyshape@#1@\endcsname}\fi
 \DN@{#2}\ifx\next@\empty
 \expandafter\def\csname xyshape@#1@\endcsname{%
 \xyundefinedStyle@{#1}{}@@}%
 \else \expandafter\def\csname xyshape@#1@\endcsname{#2}\fi}
\xydef@\xyundefinedStyle@#1#2@@{%
 \xywarning@{style #1 not defined, nothing to apply}}
\xynew@{toks}{\styletoks@}
\xydef@\addtostyletoks@#1{%
 \expandafter\styletoks@\expandafter{\the\styletoks@#1}}
\xydef@\applyFIFOstyle@#1#2#3#4{\bgroup
 \styletoks@={\egroup\gdef\preXY@style@}%
 \expandafter\toks@\expandafter{\preXY@style@}%
 \expandafter\addtotoks@\expandafter{\expandafter#1\expandafter{#2}}%
 \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}%
 \gdef\postXY@style@}%
 \expandafter\toks@\expandafter{\expandafter#3\expandafter{#4}}%
 \expandafter\addtotoks@\expandafter{\postXY@style@}%
 \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}}%
 \the\styletoks@ }
\xydef@\applyLIFOstyle@#1#2#3#4{\bgroup
 \styletoks@={\egroup\gdef\preXY@style@}%
 \expandafter\toks@\expandafter{\expandafter#1\expandafter{#2}}%
 \expandafter\addtotoks@\expandafter{\preXY@style@}%
 \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}%
 \gdef\postXY@style@}%
 \expandafter\toks@\expandafter{\postXY@style@}%
 \expandafter\addtotoks@\expandafter{\expandafter#3\expandafter{#4}}%
 \expandafter\addtostyletoks@\expandafter{\expandafter{\the\toks@}}%
 \the\styletoks@ }
\xydef@\OBJECT@direction{\afterDIRECTIONorEMPTY{%
 \edef\next@{{\DirectionfromtheDirection@}}\expandafter\addtotoks@\next@
 \xyFN@\OBJECT@}%
 {\xyFN@\OBJECT@}}
\xydef@\afterDIRECTIONorEMPTY#1#2{%
 \DN@##1{\def\afterDIRECTION@{\def\afterDIRECTION@{##1}%
 \ifDIRECTIONempty@\DN@{#2}\else\DN@{#1}\fi \next@}}%
 \expandafter\next@\expandafter{\afterDIRECTION@}%
 \xyFN@\DIRECTION@}
\xylet@\afterDIRECTION@=\empty
\xynew@{if}\ifDIRECTIONempty@
\xydef@\DIRECTION@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\DIRECTION@}%
 \else\ifx v\next \DN@ v{\DIRECTION@v}%
 \else\ifx \bgroup\next \let\next@=\DIRECTION@group
 \else\ifx (\next \DN@({\xyFN@\DIRECTION@open}%
 \else
 \DN@{\count@=8
 \afterDIAG{\ifnum\count@=8 \DN@{\DIRECTIONempty@true \xyFN@\DIRECTION@i}%
 \else \DN@{\xy@@{\dimen@=\xydashl@}\Directionfromdiag@}\fi \next@}}%
 \fi\fi\fi\fi \next@}
\xydef@\DIRECTION@open{%
 \ifx *\next \DN@*##1*){\DIRECTION@group{##1}}%
 \else \DN@{\xyerror@{(* <pos> *) expected}{} \xyFN@\DIRECTION@i}%
 \fi \next@}
\def\afterDIAG#1{\def\afterDIAG@{#1}\xyFN@\DIAG@}
\xydef@\DIAG@{%
 \ifx d\next \DN@ d{\count@=1 \xyFN@\DIAG@@}%
 \else\ifx r\next \DN@ r{\count@=3 \xyFN@\DIAG@@}%
 \else\ifx u\next \DN@ u{\count@=5 \xyFN@\DIAG@@}%
 \else\ifx l\next \DN@ l{\count@=7 \xyFN@\DIAG@@}%
 \else \let\next@=\afterDIAG@
 \fi\fi\fi\fi \next@}
\xydef@\DIAG@@{\ifcase\count@ \or
 \DIAG@@@ l0r2\or\or \DIAG@@@ d2u4\or\or \DIAG@@@ r4l6\or\or \DIAG@@@ u6d0%
 \else\xybug@{impossible <diag> number}\fi
 \next@}
\xydef@\DIAG@@@#1#2#3#4{%
 \ifx #1\next \count@=#2\DN@#1{\afterDIAG@}%
 \else \ifx #3\next \count@=#4\DN@#3{\afterDIAG@}%
 \else \let\next@=\afterDIAG@ \fi\fi}
\xydef@\Directionfromdiag@{\ifcase\count@
 \xy@@{\dlDirection@\dimen@}%
 \or \xy@@{\dDirection@\dimen@}%
 \or \xy@@{\drDirection@\dimen@}%
 \or \xy@@{\rDirection@\dimen@}%
 \or \xy@@{\urDirection@\dimen@}%
 \or \xy@@{\uDirection@\dimen@}%
 \or \xy@@{\ulDirection@\dimen@}%
 \or \xy@@{\lDirection@\dimen@}%
 \or
 \else\xybug@{impossible <diag>}\fi
 \DIRECTIONempty@false\xyFN@\DIRECTION@i}
\xydef@\DIRECTION@v{%
 \xy@{v}{\enter@{\cfromthec@ \X@origin=\the\X@origin \Y@origin=\the\Y@origin
 \X@p=\the\X@p \Y@p=\the\Y@p}%
 \X@origin=\z@ \Y@origin=\z@}%
 \afterVECTORorEMPTY
 {\xy@@{\X@p=\z@ \Y@p=\z@ \setupDirection@ \leave@}%
 \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
 {\xy@@\leave@ \xyerror@{<vector> expected after v}{}%
 \DIRECTIONempty@false \xyFN@\DIRECTION@i}}
\xydef@\DIRECTION@group#1{%
 \xy@@{\begingroup}\xy@@ix@{#1}\xy@@{\plainxy@\expandafter\POS\the\toks9\relax
 \setupDirection@\edef\next@{\endgroup \DirectionfromtheDirection@}\next@}%
 \DIRECTIONempty@false \xyFN@\DIRECTION@i}
\xydef@\DIRECTION@i{%
 \ifx ^\next \DN@ ^{\xy@^{\aboveDirection@\xydashl@}%
 \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
 \else\ifx _\next \DN@ _{\xy@_{\belowDirection@\xydashl@}%
 \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
 \else\ifx :\next \DN@ :{%
 \xy@{:}{\enter@{\cfromthec@ \basefromthebase@ \X@p=\the\X@p \Y@p=\the\Y@p}%
 \X@origin=\z@ \Y@origin=\z@
 \X@xbase=\cosDirection\xydashl@ \Y@xbase=\sinDirection\xydashl@
 \X@ybase=-\Y@xbase \Y@ybase=\X@xbase}%
 \afterVECTORorEMPTY
 {\xy@@{\X@p=\z@ \Y@p=\z@ \setupDirection@ \leave@}%
 \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
 {\xy@@\leave@ \xyerror@{<vector> expected after :}{}%
 \DIRECTIONempty@false \xyFN@\DIRECTION@i}}%
 \else
 \let\next@=\afterDIRECTION@
 \fi\fi\fi \next@}
\message{decorations;}
\xydef@\drop#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
 \xy@{\drop#1{##1}}{\expandafter\drop@\the\toks9}\ignorespaces}\next@}
\xydef@\connect#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
 \xy@{\connect#1{##1}}{\expandafter\connect@\the\toks9}\ignorespaces}\next@}
\xydef@\save{\relax\saveC}
\xydef@\saveC{\xy@\save\save@ \POS}
\xydef@\save@{\enter@{\cfromthec@ \pfromthep@ \basefromthebase@}}
\xydef@\restore{\xy@\restore\leave@ \ignorespaces}
\xydef@\xyecho{%
 \xy@\xyecho{\let\xy@=\xyecho@ \message{\string\xyecho}}\POS}
\xydef@\xyecho@#1#2{{\def\1{#1}\ifx\1\empty\else\message{\codeof\1}\fi}%
 \oxy@{#1}{#2}}
\xydef@\xyverbose{%
 \xy@\xyverbose{\let\xy@=\xyverbose@
 \W@{Xy: \string\xyverbose\xytracelineno@}}\POS}
\xydef@\xyverbose@#1#2{%
 {\def\1{#1}\ifx\1\empty\else\W@{Xy: \codeof\1\xytracelineno@}\fi}%
 \oxy@{#1}{#2}}
\xydef@\xytracing{%
 \xy@\xytracing{\let\xy@=\xytracing@
 \W@{Xy TRACE: \string\xytracing\xytracelineno@}\xystatus@:}\POS}
\xydef@\xytracing@#1#2{{\def\1{#1}\def\2{#2}%
 \W@{Xy TRACE: \codeof\1 {\codeof\2}\xytracelineno@}}\oxy@{#1}{#2}\xystatus@:}
\xydef@\xystatus@#1{%
 \W@{#1 c=<\the\X@c,\the\Y@c> \expandafter\string\the\Edge@c
 \string[\the\L@c+\the\R@c,\the\D@c+\the\U@c\string]}%
 \W@{#1 p=<\the\X@p,\the\Y@p> \expandafter\string\the\Edge@p
 \string[\the\L@p+\the\R@p,\the\D@p+\the\U@p\string]}%
 \W@{#1 [d=<\the\d@X,\the\d@Y>
 Direction=\the\Direction=\string(\cosDirection,\sinDirection\string)]
 S=\the\csp@}%
 \W@{#1 base = <\the\X@origin,\the\Y@origin> +
 x\string*<\the\X@xbase,\the\Y@xbase> +
 y\string*<\the\X@ybase,\the\Y@ybase>}%
 \W@{#1 min/max = <\the\X@min,\the\Y@min> / <\the\X@max,\the\Y@max>}}
\xydef@\xyquiet{\xy@\xyquiet{\let\xy@=\oxy@}}
\xydef@\xyignore#1{\xy@\xyignore{\xyignore@{#1}}\ignorespaces}
\xydef@\xyignore@#1{{\let\xy@=\xyeat@ \let\oxy@=\xy@ \POS#1\relax}}
\xydef@\xyeat@#1#2{}
\xydef@\xycompile@@{\jobname-}
\xydef@\xycompileno@@{0}
\xydef@\CompilePrefix#1{%
 \def\xycompile@@{#1}\xdef\xycompile@@{\codeof\xycompile@@}%
 \xdef\xycompileno@@{0}}
\xydef@\xycompile{%
 \count@=\xycompileno@@ \advance\count@\@ne
 \xdef\xycompileno@@{\ifnum10>\count@ 0\fi \the\count@}%
 \edef\next{\noexpand\xycompileto{\xycompile@@\xycompileno@@}}\next}
\xylet@\compilename@@=\empty
\xylet@\xyrecompile@@=\relax
\xydef@\xycompileto#1#2{%
 \if\inxy@ \DN@{\xy@@{\nter@{}}}%
 \else \DN@{\xy \xy@@{\nter@{\endxy}}}\fi \next@
 \ifxysaving@ \xyerror@{Compilations can not be nested}{}\fi
 \DN@{#1}\edef\compilename@@{\codeof\next@}\DNii@{#2}%
 \def\xyrecompile@@{recompiling TRUNCATED}%
 \expandafter\xyinputorelse@\expandafter{\compilename@@.xyc}%
 {\def\xyrecompile@@{compiling to}}%
 \ifx\xyrecompile@@\relax\else \expandafter\xyrecompile@ \fi \xy@@\leave@
 \ignorespaces}
\xydef@\xyrecompile@{%
 \message{(\xyrecompile@@\space\string`\compilename@@.xyc\string'}%
 \DN@{\immediate\openout\xywrite@=}\expandafter\next@\compilename@@.xyc
 \immediate\write\xywrite@{%
 \string\xycompiled{\compilename@@}%
 {\the\year/\the\month/\the\day\string:\the\time\xytracelineno@}%
 {Xy-pic \xyversion}\xycomment@}%
 \immediate\write\xywrite@{{\codeof\nextii@}\relax}%
 {\xysaving@ \expandafter\POS\nextii@ \relax}%
 \immediate\write\xywrite@{\string\xyendcompiled}%
 \immediate\closeout\xywrite@ \message{done)}%
 \expandafter\input\compilename@@.xyc }
\xydef@\xysaving@{\let\xy@=\xysave@ \let\oxy@=\xy@
 \let\xy@@ix@=\xysave@@toksix@ \xysaving@true}
\xynew@{if}\ifxysaving@ \xysaving@false
\xydef@\xysave@#1#2{{\DN@{{#1}{#2}}%
 \immediate\write\xywrite@{\string\xy@\codeof\next@\xycomment@}}}
\xydef@\xysave@@toksix@#1{{\DN@{{#1}}%
 \immediate\write\xywrite@{\string\xy@@ix@\codeof\next@\relax}}}
\xywarnifdefined\xycomment@
{\catcode`\%=12 \catcode`\(=1 \catcode`\)=2 \gdef\xycomment@(%)}
\xydef@\xycompiled#1#2#3#4{\DN@{#1}\edef\next@{\codeof\next@}%
 \ifx\next@\compilename@@\else
 \xywarning@{This file does not contain the result of
 \string\xycompileto{\compilename@@}{...}^^J%
 but of \string\xycompileto{\next@}}\fi
 \edef\next{Xy-pic \xyversion}\DN@{#3}\ifx\next\next@
 \DN@{#4}\ifx\next@\nextii@ \xycatcodes
 \else \def\xyrecompile@@{recompiling to}\endinput \fi
 \else \def\xyrecompile@@{Xy-pic version change - recompiling}\endinput \fi}
\xydef@\xyendcompiled{\let\xyrecompile@@=\relax \xyuncatcodes\endinput}
\message{kernel objects:}
\message{directionals,}
\xydef@\dir{\hbox\bgroup\xyFN@\dir@i}
\xydef@\dir@i{\ifx *\next \DN@*{\object@}\else \let\next@=\dir@ii \fi \next@}
\xydef@\dir@ii#1#{\dir@{#1}}
\xydef@\dir@#1#2{\DN@{dir#1{#2}}%
 \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
 \ifx\next\relax \DN@{dir{#2}}%
 \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
 \ifx\next\relax \DN@{\dir#1{#2}}%
 \xyerror@{illegal <dir>: \codeof\next@\space not defined}{}%
 \let\next=\no@ \fi\fi \next}
\xydefcsname@{dir{}}{\no@}
\xyletcsnamecsname@{dir0{}}{dir{}}
\xyletcsnamecsname@{dir1{}}{dir{}}
\xyletcsnamecsname@{dir^{}}{dir{}}
\xyletcsnamecsname@{dir_{}}{dir{}}
\xyletcsnamecsname@{dir2{}}{dir{}}
\xyletcsnamecsname@{dir3{}}{dir{}}
\xyletcsnamecsname@{dir{ }}{dir{}}
\xydef@\no@{\egroup \czeroEdge@ \Invisible@false \Hidden@false
 \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\setbox\z@=\copy\voidb@x}\def\Connect@@{\no@@}}
\xydefcsname@{dir1{-}}{\line@}
\xydefcsname@{dir2{-}}{\line@ \double@\xydashh@}
\xydefcsname@{dir3{-}}{\line@ \triple@\xydashh@}
\xyletcsnamecsname@{dir0{-}}{dir{}}
\xyletcsnamecsname@{dir{-}}{dir1{-}}
\xyletcsnamecsname@{dir{=}}{dir2{-}}
\xydef@\line@{\dimen@=\sd@Y\sinDirection\xydashl@
 \ifnum\SemiDirectionChar<31 \D@c=\z@ \U@c=\dimen@ \DN@{\d@Y<\z@}%
 \else\ifnum\SemiDirectionChar<64 \D@c=\dimen@ \U@c=\z@ \DN@{\z@<\d@Y}%
 \else\ifnum\SemiDirectionChar<96 \D@c=\dimen@ \U@c=\z@ \DN@{\d@X<\z@}%
 \else \D@c=\z@ \U@c=\dimen@ \DN@{\d@X<\z@}\fi\fi\fi
 \setboxz@h{\line@@}\ht\z@=\U@c \dp\z@=\D@c
 \L@c=\z@ \R@c=\wdz@
 \ifdim\next@ \dimen@=\R@c \R@c=\L@c \L@c=\dimen@
 \dimen@=\U@c \U@c=\D@c \D@c=\dimen@ \advance\dimen@-\U@c
 \lower\dimen@\boxz@
 \else \boxz@ \fi
 \edef\tmp@{\egroup \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c}%
 \tmp@
 \Edge@c={\rectangleEdge}\Invisible@false\Hidden@false
 \ifdim\z@<\U@c \def\Upness@{1}\else \def\Upness@{0}\fi
 \ifdim\z@<\L@c \def\Leftness@{1}\else \def\Leftness@{0}\fi
 \def\Drop@@{\boxz@}\def\Connect@@{\solid@}}
\xydef@\line@@{{\xydashfont\SemiDirectionChar\/}}
\xydef@\solid@{%
 \ifInvisible@ \DN@{\no@@}%
 \else \dimen@=\Y@c \advance\dimen@-\Y@p
 \ifjusthvtest@.05pt>\ifdim\dimen@<\z@-\fi\dimen@ \DN@{\solidhrule@}%
 \else \dimen@=\X@c \advance\dimen@-\X@p
 \ifjusthvtest@.05pt>\ifdim\dimen@<\z@-\fi\dimen@ \DN@{\solidvrule@}%
 \else \DN@{\straight@\solidSpread@}\fi\fi\fi
 \next@}
\xydef@\solidSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi}
\xylet@\ifjusthvtest@=\ifdim
\xydef@\NoRules{\let\ifjusthvtest@=\iffalse}
\xydef@\UseRules{\let\ifjusthvtest@=\ifdim}
\xydef@\solidvrule@{\no@@{%
 \ifdim\Y@c<\Y@p \dimen@=\Y@c \Y@c=\Y@p \Y@p=\dimen@ \advance\Y@c-\D@p \advance\Y@p\U@c
 \else \advance\Y@c-\D@c \advance\Y@p\U@p \fi
 \advance\X@c-.5\xydashw@
 \setboxz@h{\kern\X@c \vrule width\xydashw@ height\Y@c depth-\Y@p}%
 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}}
\xydef@\solidhrule@{\no@@{%
 \ifdim\X@c<\X@p \advance\X@c\R@c \advance\X@p-\L@p
 \else \dimen@=\X@c \X@c=\X@p \X@p=\dimen@ \advance\X@c\R@p \advance\X@p-\L@c \fi
 \advance\X@p-\X@c \advance\Y@c.5\xydashw@ \advance\Y@p-.5\xydashw@
 \setboxz@h{\kern\X@c \vrule width\X@p height\Y@c depth-\Y@p}%
 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}}
\xydef@\zerodot{\copy\zerodotbox@}
\xydefcsname@{dir1{.}}{\point@}
\xydefcsname@{dir2{.}}{\point@ \double@\xydashh@}
\xydefcsname@{dir3{.}}{\point@ \triple@\xydashh@}
\xyletcsnamecsname@{dir0{.}}{dir{}}
\xyletcsnamecsname@{dir{.}}{dir1{.}}
\xyletcsnamecsname@{dir{:}}{dir2{.}}
\xydef@\point@{\pointlike@\zerodot\p@}
\xydef@\pointlike@#1#2{%
 \setboxz@h{#1}\wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@\egroup
 \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}\ctipEdge@
 \def\Drop@@{\boxz@}\def\Connect@@{\straight@{\dottedSpread@{#2}}}}
\xydef@\dottedSpread@#1{\setupDirection@
 \dimen@=#1\relax \dimen@=2\dimen@
 \A@=\sd@X\cosDirection\dimen@ \B@=\sd@Y\sinDirection\dimen@
 \global\setbox\lastobjectbox@=\hbox to\A@{\hss
 \kern.5\A@\box\lastobjectbox@\kern.5\A@\hss}%
 \dp\lastobjectbox@=.5\B@ \ht\lastobjectbox@=.5\B@
 \advance\d@X\sd@X\A@ \advance\d@Y\sd@Y\B@
 \advance\X@c\sd@X.5\A@ \advance\Y@c\sd@Y.5\B@
 \ifdim\sd@Y\d@Y<\sd@X\d@X \dimen@=\sd@X\d@X
 \ifdim\zz@\A@\else \divide\dimen@\A@ \fi \count@@=\dimen@
 \else\ifdim\z@=\sd@Y\d@Y\else
 \dimen@=\sd@Y\d@Y \ifdim\zz@\B@\else \divide\dimen@\B@ \fi \count@@=\dimen@
 \fi\fi \advance\count@@\@ne}
\xydefcsname@{dir1{~}}{\squiggle@}
\xydefcsname@{dir2{~}}{\squiggle@ \double@\xybsqlh@}
\xydefcsname@{dir3{~}}{\squiggle@ \triple@\xybsqlh@}
\xyletcsnamecsname@{dir0{~}}{dir{}}
\xyletcsnamecsname@{dir{~}}{dir1{~}}
\xydef@\squiggle@{\xybsqlfont
 \dimen@=\sd@X\cosDirection\xybsqll@ \advance\dimen@.1\p@
 \dimen@ii=\sd@Y\sinDirection\xybsqll@
 \kern\dimen@\squiggle@@
 \edef\tmp@{\egroup \U@c=\the\dimen@ii \L@c=\the\dimen@}\tmp@
 \wdz@=2\L@c \R@c=\L@c \ht\z@=\U@c \D@c=\U@c \dp\z@=\U@c \Edge@c={\rectangleEdge}%
 \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\boxz@}\def\Connect@@{\straight@\squiggledSpread@}}
\xydef@\squiggle@@{\DirectionChar \count@=\DirectionChar
 \advance\count@-64 \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}
\xydef@\squiggledSpread@{%
 \dimen@=\d@X \advance\dimen@-\sd@X\count@@\A@ \advance\dimen@\sd@X.3\p@
 \advance\X@c-.5\dimen@ \advance\d@X-\dimen@
 \dimen@=\d@Y \advance\dimen@-\sd@Y\count@@\B@ \advance\dimen@\sd@Y.3\p@
 \advance\Y@c-.5\dimen@ \advance\d@Y-\dimen@}
\xydef@\double@#1{\edef\Drop@@{\dimen@=#1\relax
 \dimen@=.5\dimen@ \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
 \setbox2=\hbox{\kern\A@\raise\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2
 \setbox2=\hbox{\kern-\A@\raise-\B@\boxz@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 }}
\xydef@\triple@#1{\edef\Drop@@{\dimen@=#1\relax
 \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
 \setbox2=\hbox{\kern\A@\raise\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2
 \setbox2=\hbox{\kern-\A@\raise-\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2
 \dp\z@=\z@ \ht\z@=\z@ \wdz@=\z@ \boxz@}}
\xydefcsname@{dir1{--}}{\dash@}
\xydefcsname@{dir2{--}}{\dash@ \double@\xydashh@}
\xydefcsname@{dir3{--}}{\dash@ \triple@\xydashh@}
\xyletcsnamecsname@{dir0{--}}{dir{}}
\xyletcsnamecsname@{dir{--}}{dir1{--}}
\xyletcsnamecsname@{dir{==}}{dir2{--}}
\xydef@\dash@{\line@ \wdz@=2\wdz@ \ht\z@=2\ht\z@ \dp\z@=2\dp\z@
 \multiply\D@c\tw@ \multiply\U@c\tw@ \multiply\L@c\tw@ \multiply\R@c\tw@
 \def\Connect@@{\straight@\dashedSpread@}}
\xydef@\dashedSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi
 \advance\d@X\sd@X.5\A@ \advance\d@Y\sd@Y.5\B@
 \ifdim\z@<\d@X \advance\X@c.5\A@ \fi \advance\Y@c\sd@Y.5\B@}
\xydefcsname@{dir1{~~}}{\dashsquiggle@}
\xydefcsname@{dir2{~~}}{\dashsquiggle@ \double@\xybsqlh@}
\xydefcsname@{dir3{~~}}{\dashsquiggle@ \triple@\xybsqlh@}
\xyletcsnamecsname@{dir0{~~}}{dir{}}
\xyletcsnamecsname@{dir{~~}}{dir1{~~}}
\xydef@\dashsquiggle@{\squiggle@
 \multiply\D@c\tw@ \multiply\U@c\tw@ \multiply\L@c\tw@ \multiply\R@c\tw@
 \dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@ \ht\z@=\U@c \dp\z@=\D@c
 \def\Connect@@{\straight@\dashsquiggledSpread@}}
\xydef@\dashsquiggledSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi
 \advance\X@c.5\A@ \advance\d@X.5\A@ \advance\Y@c.25\B@ \advance\d@Y.5\B@}
\xyletcsnamecsname@{dir1{..}}{dir{.}}
\xyletcsnamecsname@{dir2{..}}{dir2{.}}
\xyletcsnamecsname@{dir3{..}}{dir3{.}}
\xyletcsnamecsname@{dir{..}}{dir1{.}}
\xyletcsnamecsname@{dir{::}}{dir2{.}}
\xylet@\ctipEdge@=\czeroEdge@
\xydefcsname@{dir1{>}}{\tip@}
\xydefcsname@{dir^{>}}{\atip@}
\xydefcsname@{dir_{>}}{\btip@}
\xyletcsnamecsname@{dir0{>}}{dir{}}
\xyletcsnamecsname@{dir{>}}{dir1{>}}
\xydefcsname@{dir1{<}}{\reverseDirection@\tip@}
\xydefcsname@{dir^{<}}{\reverseDirection@\btip@}
\xydefcsname@{dir_{<}}{\reverseDirection@\atip@}
\xyletcsnamecsname@{dir0{<}}{dir{}}
\xyletcsnamecsname@{dir{<}}{dir1{<}}
\xydef@\tip@{\tip@x\tip@@}
\xydef@\atip@{\tip@x\atip@@}
\xydef@\btip@{\tip@x\btip@@}
\xydef@\tip@x#1{#1\egroup
 \ctipEdge@ \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\boxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
\xydef@\tip@@{\atip@@\btip@@}
\xydef@\atip@@{\xyatipfont\DirectionChar}
\xydef@\btip@@{\xybtipfont\DirectionChar}
\xydefcsname@{dir2{>}}{\Tip@}
\xydefcsname@{dir2{<}}{\reverseDirection@\Tip@}
\xydef@\Tip@{\kern2.5pt \vrule height2.5pt depth2.5pt width\z@
 \Tip@@ \kern2.5pt \egroup
 \U@c=2.5pt \D@c=2.5pt \L@c=2.5pt \R@c=2.5pt \Edge@c={\circleEdge}%
 \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\boxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
\xydef@\Tip@@{\count@=\DirectionChar
 \advance\count@-4 \ifnum\count@<\z@ \advance\count@128 \fi
 \xyatipfont\char\count@
 \advance\count@ 8 \ifnum127<\count@ \advance\count@-128 \fi
 \xybtipfont\char\count@}
\xydefcsname@{dir3{>}}{\Ttip@}
\xydefcsname@{dir3{<}}{\reverseDirection@\Ttip@}
\xydef@\Ttip@{\kern3.2pt \vrule height3.2pt depth3.2pt width\z@
 \Ttip@@ \kern3.2pt \egroup
 \U@c=3.2pt \D@c=3.2pt \L@c=3.2pt \R@c=3.2pt \Edge@c={\circleEdge}%
 \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\boxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
\xydef@\Ttip@@{%
 \setboxz@h\bgroup\reverseDirection@\line@ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@
 \kern-\L@c \boxz@ \kern\L@c
 {\vDirection@(1,-.31)\xydashl@ \xyatipfont\char\DirectionChar}%
 {\vDirection@(1,+.31)\xydashl@ \xybtipfont\char\DirectionChar}}
\xydefcsname@{dir1{|}}{\stopper@}
\xydefcsname@{dir^{|}}{\aboveDirection@\xydashl@
 \shiftdir@\line@\z@ \pointlike@{}\xydashh@}
\xydefcsname@{dir_{|}}{\belowDirection@\xydashl@
 \shiftdir@\line@\z@ \pointlike@{}\xydashh@}
\xydefcsname@{dir2{|}}{\stopper@ \double@\xydashh@}
\xydefcsname@{dir3{|}}{\stopper@ \double@{2\xydashh@}}
\xyletcsnamecsname@{dir0{|}}{dir{}}
\xyletcsnamecsname@{dir{|}}{dir1{|}}
\xydef@\stopper@{\tip@x\stopper@@}
\xydef@\stopper@@{\setboxz@h{\count@=\SemiDirectionChar \advance\count@64
 \ifnum127<\count@ \advance\count@-128 \fi \xydashfont\char\count@\/}%
 \setboxz@h{\kern-.5\wdz@ \dimen@=\sd@Y\cosDirection\xydashl@ 
 \ifnum\SemiDirectionChar=95 \dimen@=\sd@X\sd@Y\dimen@ \fi
 \raise.5\dimen@\boxz@}%
 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
\xydefcsname@{dir1{(}}{\hook@}
\xydefcsname@{dir^{(}}{\ahook@}
\xydefcsname@{dir_{(}}{\bhook@}
\xyletcsnamecsname@{dir0{(}}{dir{}}
\xyletcsnamecsname@{dir{(}}{dir1{(}}
\xydefcsname@{dir1{)}}{\reverseDirection@\hook@}
\xydefcsname@{dir^{)}}{\reverseDirection@\bhook@}
\xydefcsname@{dir_{)}}{\reverseDirection@\ahook@}
\xyletcsnamecsname@{dir0{)}}{dir{}}
\xyletcsnamecsname@{dir{)}}{dir1{)}}
\xydef@\hook@{\tip@x\hook@@}
\xydef@\hook@@{\setboxz@h{\xybsqlfont
 \vDirection@(1,-1){.707107\xybsqll@}%
 \hbox{\DirectionChar
 \kern-\d@Y\raise\d@X\hbox{\count@=\DirectionChar \advance\count@-32
 \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}}%
 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
\xydef@\ahook@{\tip@x\ahook@@}
\xydef@\ahook@@{\setboxz@h{\xybsqlfont
 \vDirection@(1,-1){.707107\xybsqll@}\kern-\d@X
 \lower\d@Y\hbox{\DirectionChar
 \kern-\d@Y\raise\d@X\hbox{\count@=\DirectionChar \advance\count@-32
 \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}}%
 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
\xydef@\bhook@{\tip@x\bhook@@}
\xydef@\bhook@@{\setboxz@h{\xybsqlfont
 \vDirection@(-1,-1){.707107\xybsqll@}\DirectionChar
 \kern\d@X\raise\d@Y\hbox{\count@=\DirectionChar \advance\count@-96
 \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}%
 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
\xydefcsname@{dir^{'}}{\reverseDirection@\bturn@}
\xydefcsname@{dir_{'}}{\reverseDirection@\aturn@}
\xydefcsname@{dir^{`}}{\aturn@}
\xydefcsname@{dir_{`}}{\bturn@}
\xydef@\aturn@{\tip@x\aturn@@}
\xydef@\aturn@@{\setboxz@h{\xybsqlfont
 \vDirection@(1,-1){.707107\xybsqll@}\kern-\d@X
 \lower\d@Y\hbox{\DirectionChar}}%
 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
\xydef@\bturn@{\tip@x\bturn@@}
\xydef@\bturn@@{\setboxz@h{\xybsqlfont
 \vDirection@(-1,-1){.707107\xybsqll@}\DirectionChar}%
 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
\xydef@\newdir#1#{\newdir@{#1}}
\xydef@\newdir@#1#2#3{\xydefcsname@{dir#1{#2}}{\composite@{}{#3}}}
\xydef@\shiftdir@#1#2{%
 \setbox\z@=\hbox\bgroup#1\relax
 \setboxz@h{\dimen@ii=#2\relax
 \dimen@=-\cosDirection\dimen@ii \advance\dimen@-\L@c
 \kern\dimen@ \lower\sinDirection\dimen@ii\boxz@}%
 \wdz@\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
\xylet@\tipjot@=\jot
\xydefcsname@{dir1{>>}}{\shiftdir@\tip@\tipjot@ \tip@}
\xydefcsname@{dir^{>>}}{\shiftdir@\atip@\tipjot@ \atip@}
\xydefcsname@{dir_{>>}}{\shiftdir@\btip@\tipjot@ \btip@}
\xydefcsname@{dir2{>>}}{\composite@{}{h!/\tipjot@/\dir2{>}*\dir2{>}}}
\xydefcsname@{dir3{>>}}{\composite@{}{h!/\tipjot@/\dir3{>}*\dir3{>}}}
\xyletcsnamecsname@{dir0{>>}}{dir{}}
\xyletcsnamecsname@{dir{>>}}{dir1{>>}}
\xydefcsname@{dir1{<<}}{\reverseDirection@ \shiftdir@\tip@\tipjot@ \tip@}
\xydefcsname@{dir^{<<}}{\reverseDirection@ \shiftdir@\btip@\tipjot@ \btip@}
\xydefcsname@{dir_{<<}}{\reverseDirection@ \shiftdir@\atip@\tipjot@ \atip@}
\xydefcsname@{dir2{<<}}{\composite@{}{h!/-\tipjot@/\dir2{<}*\dir2{<}}}
\xydefcsname@{dir3{<<}}{\composite@{}{h!/-\tipjot@/\dir3{<}*\dir3{<}}}
\xyletcsnamecsname@{dir0{<<}}{dir{}}
\xyletcsnamecsname@{dir{<<}}{dir1{<<}}
\xydefcsname@{dir{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
 \pointlike@{}\jot}
\xydefcsname@{dir^{||}}{\shiftdir@{\aboveDirection@\xydashl@\line@}\xydashh@
 \shiftdir@{\aboveDirection@\xydashl@\line@}\z@ \pointlike@{}\jot}
\xydefcsname@{dir_{||}}{\shiftdir@{\belowDirection@\xydashl@\line@}\xydashh@
 \shiftdir@{\belowDirection@\xydashl@\line@}\z@ \pointlike@{}\jot}
\xydefcsname@{dir2{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
 \pointlike@{}\jot \double@\xydashh@}
\xydefcsname@{dir3{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
 \pointlike@{}\jot \double@{2\xydashh@}}
\xydefcsname@{dir{>|}}{\shiftdir@\stopper@\z@ \tip@}
\xydefcsname@{dir2{>|}}{\composite@{}{\dir2{>}*\dir2{|}}}
\xydefcsname@{dir3{>|}}{\composite@{}{\dir3{>}*\dir3{|}}}
\xydefcsname@{dir{>>|}}{\shiftdir@\stopper@\z@ \shiftdir@\tip@\tipjot@ \tip@}
\xydefcsname@{dir2{>>|}}{\composite@{}{h!/\tipjot@/\dir2{>}*\dir2{>}*\dir2{|}}}
\xydefcsname@{dir3{>>|}}{\composite@{}{h!/\tipjot@/\dir3{>}*\dir3{>}*\dir3{|}}}
\xydefcsname@{dir{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \tip@}
\xydefcsname@{dir2{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \Tip@}
\xydefcsname@{dir3{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \Ttip@}
\xydefcsname@{dir{|<<}}{\reverseDirection@
 \shiftdir@\stopper@\z@ \shiftdir@\tip@\tipjot@ \tip@}
\xydefcsname@{dir2{|<<}}{%
 \composite@{}{h!/-\tipjot@/\dir2{<}*\dir2{<}*\dir2{|}}}
\xydefcsname@{dir3{|<<}}{%
 \composite@{}{h!/-\tipjot@/\dir3{<}*\dir3{<}*\dir3{|}}}
\xydefcsname@{dir{|-}}{\shiftdir@\stopper@\z@
 \shiftdir@\line@\z@ \pointlike@{}\jot}
\xydefcsname@{dir^{|-}}{\shiftdir@{\aboveDirection@\xydashl@ \line@}\z@
 \shiftdir@\line@\z@ \pointlike@{}\jot}
\xydefcsname@{dir_{|-}}{\shiftdir@{\belowDirection@\xydashl@ \line@}\z@
 \shiftdir@\line@\z@ \pointlike@{}\jot}
\xydefcsname@{dir2{|-}}{\shiftdir@\stopper@\z@
 \shiftdir@\line@\z@ \pointlike@{}\jot \double@\xydashh@}
\xydefcsname@{dir3{|-}}{\shiftdir@\stopper@\z@
 \shiftdir@\line@\z@ \pointlike@{}\jot \triple@\xydashh@}
\xyletcsnamecsname@{dir0{|=}}{dir{}}
\xyletcsnamecsname@{dir{|=}}{dir2{|-}}
\xydefcsname@{dir{+}}{%
 \DN@##1{\composite@{}{##10\dir{|}*!C##10\dir{-}}}\addEQ@\next@}
\xydefcsname@{dir{x}}{\vDirection@(1,1)\jot
 \DN@##1{\composite@{}{##10\dir{|}*!C##10\dir{-}}}\addEQ@\next@}
\xydefcsname@{dir{/}}{\vDirection@(1,-.3)\jot \stopper@}
\xydefcsname@{dir{//}}{\vDirection@(1,-.3)\jot
 \shiftdir@\stopper@\xydashh@ \stopper@}
\xydefcsname@{dir{*}}{\solidpoint@}
\xydef@\solidpoint@{%
 \pointlike@{\kern-1.8pt\lower1.8pt\hbox{$\scriptstyle\bullet$}}\jot}
\xydefcsname@{dir{o}}{\hollowpoint@}
\xydef@\hollowpoint@{%
 \pointlike@{\kern-1.8pt\lower1.8pt\hbox{$\scriptstyle\circ$}}\jot}
\message{circles,}
\xydef@\cir#1#{\hbox\bgroup
 \afterVECTORorEMPTY{\xy@@{\R@=\X@c}\cir@}{\xy@@{\R@=\R@c}\cir@}#1@}
\xydef@\cir@#1@#2{%
 \DN@{#1}\ifx\next@\empty\else \xyerror@{illegal circle <radius>: must be
 <vector> or <empty>}{}\fi
 \afterCIRorDIAG{\xyFN@\cir@cir}{\xyFN@\cir@diag}#2@}
\xydef@\cir@cir{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\cir@cir}%
 \else \ifx @\next \DN@ @{\cir@i}%
 \else \xyerror@{illegal <cir>: must have form <diag><orient><diag> or
 <empty>}{}%
 \fi\fi \next@}
\xydef@\cir@diag{%
 \DN@{\xyerror@{illegal <cir>: must have form <diag><orient><diag> or
 <empty>}{}}%
 \ifx @\next \ifnum\count@=8
 \DN@ @{\def\CIRin@@{0}\def\CIRorient@@{\CIRfull@}\def\CIRout@@{7}\cir@i}%
 \fi\fi \next@}
\xydef@\cir@i{%
 \ifnum\CIRin@@=8 \xyerror@{incomplete <cir> specification}{%
The <cir> you specified as <diag><orient><diag> is not sufficiently specific.}%
 \def\CIRin@@{0}\fi
 \ifdim\R@<.5\p@ \R@=\z@ \zerodot
 \else \CIRorient@@ \cirbuild@ \fi
 \L@c=\R@ \R@c=\R@ \D@c=\R@ \U@c=\R@ \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\boxz@}\def\Connect@@{\straight@\relax}\Edge@c={\circleEdge}%
 \OBJECT@x}
\xydef@\CIRin@@{3}
\xydef@\CIRout@@{3}
\xylet@\CIRorient@@=\empty
\xydef@\afterCIRorDIAG#1#2{\def\afterCIR@{#1}\def\afterCIRDIAG@{#2}\xyFN@\CIR@}
\xylet@\afterCIR@=\empty
\xylet@\afterCIRDIAG@=\empty
\xydef@\CIR@{\count@=8 \afterDIAG{\edef\CIRin@@{\the\count@}\xyFN@\CIR@@}}
\xydef@\CIR@@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\CIR@@}%
 \else\ifx ^\next
 \DN@ ^{\def\CIRorient@@{\CIRacw@}%
 \afterDIAG{\edef\CIRout@@{\the\count@}\afterCIR@}}%
 \else\ifx _\next
 \DN@_{\def\CIRorient@@{\CIRcw@}%
 \afterDIAG{\edef\CIRout@@{\the\count@}\afterCIR@}}%
 \else
 \DN@{\def\CIRorient@@{\relax}\afterCIRDIAG@}%
 \fi\fi\fi \next@}
\xylet@\CIRtest@@=\relax
\xydef@\CIRlo@@{0}
\xydef@\CIRhi@@{0}
\xydef@\CIRfull@{\def\CIRtest@@##1##2{##2}}
\xydef@\cirbuild@{\cirrestrict@@ \multiply\count@8
 \circhar@0\circhar@7\kern\dimen@
 \circhar@1\circhar@6\kern\dimen@
 \circhar@2\circhar@5\kern\dimen@
 \circhar@3\circhar@4\kern\dimen@}
\xydef@\circhar@#1{%
 \setboxz@h{\circhar@@{#1}}\dimen@=\wdz@ \wdz@=\z@ \ht\z@=\R@ \dp\z@=\R@
 \CIRtest@@#1{\boxz@}\setbox\z@=\copy\voidb@x}
\xydef@\circhar@@#1{{\xycircfont \advance\count@#1\relax \char\count@}}
\xydef@\cirrestrict@@{\begingroup \dimen@=\R@
 \setboxz@h{\xycircfont\char\z@\char\@ne}\A@=\wdz@
 \ifdim\R@<8\A@ \count@=\dimen@ \divide\count@\A@ \advance\count@\m@ne
 \else\ifdim\R@<16\A@ \count@=\dimen@
 \dimen@=2\A@ \divide\count@\dimen@ \advance\count@3
 \else\ifdim\R@<32\A@ \count@=\dimen@
 \dimen@=4\A@ \divide\count@\dimen@ \advance\count@7
 \else \count@=15 \fi\fi\fi
 \R@=\A@
 \ifnum\count@<8 \multiply\R@\count@ \advance\R@\A@
 \else\ifnum\count@<12 \multiply\R@\count@ \multiply\R@\tw@ \advance\R@-6\A@
 \else\ifnum\count@<16 \multiply\R@\count@ \multiply\R@ 4 \advance\R@-28\A@
 \else \multiply\R@ 32 \fi\fi\fi
 \edef\@tmp{\endgroup \R@=\the\R@ \count@=\the\count@}\@tmp}
\xydef@\CIRacw@{\count@@=\CIRin@@ \count@=\CIRout@@
 \ifnum\count@=8 \count@=\count@@
 \ifnum\count@<6 \advance\count@\tw@ \else \advance\count@-6 \fi \fi
 \ifnum\count@@<\@ne \advance\count@@7 \else \advance\count@@\m@ne \fi
 \ifnum\count@<\@ne \advance\count@7 \else \advance\count@\m@ne \fi
 \ifnum\count@@>\count@ \let\CIRtest@@=\CIRtest@outside
 \edef\CIRlo@@{\the\count@}\edef\CIRhi@@{\the\count@@}%
 \else \let\CIRtest@@=\CIRtest@inside
 \edef\CIRlo@@{\the\count@@}\edef\CIRhi@@{\the\count@}%
 \fi}
\xydef@\CIRcw@{\count@@=\CIRin@@ \count@=\CIRout@@
 \ifnum\count@=8 \count@=\count@@
 \ifnum\count@>\@ne \advance\count@-\tw@ \else \advance\count@6 \fi \fi
 \ifnum\count@@<5 \advance\count@@\thr@@ \else \advance\count@@-5 \fi
 \ifnum\count@<5 \advance\count@\thr@@ \else \advance\count@-5 \fi
 \ifnum\count@@<\count@ \let\CIRtest@@=\CIRtest@outside
 \edef\CIRlo@@{\the\count@@}\edef\CIRhi@@{\the\count@}%
 \else \let\CIRtest@@=\CIRtest@inside
 \edef\CIRlo@@{\the\count@}\edef\CIRhi@@{\the\count@@}%
 \fi}
\xydef@\CIRtest@inside#1#2{\let\next@=\relax
 \ifnum\CIRlo@@>#1\else \ifnum#1<\CIRhi@@\DN@{#2}\fi\fi \next@}
\xydef@\CIRtest@outside#1#2{\let\next@=\relax
 \ifnum\CIRlo@@>#1\DN@{#2}\else \ifnum#1<\CIRhi@@\else\DN@{#2}\fi\fi \next@}
\message{text;}
\xydef@\txt{\hbox\bgroup \xyFN@\txt@}
\xydef@\txt@{%
 \addLT@\ifx\next \addGT@{\addLT@\DN@##1}{\A@=##1\txt@i}%
 \else \DN@{\A@=\maxdimen \txt@i}\fi \next@}
\xydef@\txt@i#1#{%
 \setboxz@h{#1\mathstrut}\dimen@=\ht\z@ \advance\dimen@\dp\z@
 \baselineskip=1.1\dimen@ \lineskip=.2\dimen@ \lineskiplimit=\lineskip
 \def\txtline@@##1{\txtline@{#1}{##1}}\object@\txt@ii}
\xylet@\txtline@@=\eat@
\xydef@\txtline@#1#2{\relax\setboxz@h{#1\ignorespaces #2\unskip}%
 \ifdim\A@<\wdz@ \setboxz@h{\hsize=\A@
 \leftskip=0pt plus4em \rightskip=\leftskip
 \parfillskip=0pt \parindent=0pt
 \spaceskip=.3333em \xspaceskip=.5em
 \pretolerance=9999 \tolerance=9999
 \hyphenpenalty=9999 \exhyphenpenalty=9999
 \vbox{#1\noindent\ignorespaces #2\unskip}}%
 \else\ifdim\A@<\maxdimen\setboxz@h to\A@{\hfil\boxz@\hfil}\fi\fi
 \boxz@}
\xydef@\txt@ii#1{\vbox{%
 \let\\=\cr
 \tabskip=\z@skip \halign{\relax\hfil\txtline@@{##}\hfil\cr#1\crcr}}}
\message{options;}
\xylet@\xyoption@@=\relax
\xydef@\xyoption#1{\DN@{#1}\edef\next@{\codeof\next@}%
 \csname xyeveryrequest@\next@ @\endcsname
 \xyinputorelse@{xy#1}{\xyinputorelse@{xy#1.doc}{\xyoption@truncated#1@}}%
 \def\xyoption@@{#1}\edef\xyoption@@{\codeof\xyoption@@}
 \expandafter\let\expandafter\next@\csname xy\xyoption@@ version\endcsname
 \expandafter\let\csname xy\xyoption@@ loaded\endcsname=\next@
 \runxywith@ \ignorespaces}
\xydef@\xyoption@truncated#1#2#3#4#5#6#7@{%
 \DN@{#7}\ifx\next@\empty \DN@##1##2{##2}\else\let\next@=\xyinputorelse@ \fi
 \next@{xy#1#2#3#4#5#6}%
 {\DN@{#1}\edef\next@{\codeof\next@}\xyerror@{No `\next@' option}{%
Your \string\xyoption\string{\next@\string}%
 request could not be granted: the required^^J%
file `xy\next@.tex' could not be located. Please make sure that it is^^J%
properly installed before continuing.}}}
\xydef@\xyrequire#1{\DN@{#1}\edef\next@{\codeof\next@}%
 \csname xyeveryrequest@\next@ @\endcsname
 \expandafter\let\expandafter\next@\csname xy\codeof\next@ loaded\endcsname
 \ifx \next@\relax \DN@{\xyoption{#1}}\else \DN@{\ignorespaces}\fi \next@}
\xylet@\xywith@@=\empty
\xydef@\runxywith@{\let\xywithdo@@=\xywithtest@ \xywith@@}
\xydef@\xywithoption#1#2{\DN@{#1}\edef\next@{\codeof\next@}%
 \expandafter\let\expandafter\nextii@\csname xy\next@ loaded\endcsname
 \ifx \nextii@\relax
 \expandafter\def\expandafter\xywith@@\expandafter{\xywith@@ 
 \xywithdo@@{#1}{#2}}%
 \else \expandafter\xywithrun@\expandafter{\next@}{#2}\fi}
\xydef@\xywithtest@#1#2{\DN@{#1}\edef\next@{\codeof\next@}%
 \ifx\next@\xyoption@@ \expandafter\xywithrun@\expandafter{\next@}{#2}\fi}
\xydef@\xywithrun@#1#2{\csname xyeverywithoption@#1@\endcsname #2}
\xydef@\xyevery@#1#2#3{\DN@{#2}\edef\next@{\codeof\next@}%
 \expandafter\ifx\csname xyevery#1@\next@ @\endcsname\relax
 \expandafter\let\csname xyevery#1@\next@ @\endcsname=\empty \fi
 \DNii@##1{\expandafter\def\expandafter##1\expandafter{##1#3}}%
 \expandafter\nextii@\csname xyevery#1@\next@ @\endcsname}
\xydef@\xyeveryrequest{\xyevery@{request}}
\xydef@\xyeverywithoption{\xyevery@{withoption}}
\xydef@\xyprovide#1#2#3#4#5#6{%
 \def\xyoption@@{#1}\edef\xyoption@@{\codeof\xyoption@@}\edef\next@{#3}%
 \message{ Xy-pic option: #2 v.\next@}%
 \expandafter\let\expandafter\nextii@\csname xy\xyoption@@ loaded\endcsname
 \ifx \next@\nextii@ \message{not reloaded}\endinput
 \else
 \ifx \nextii@\relax\else \xyerror@{Option `\xyoption@@' version mismatch}{%
You previously loaded, or the format has preloaded, a different version^^J%
of this option. Just continue to try to load this version instead (and^^J%
be prepared for a lot of warnings about redefinitions).}%
 \fi
 \expandafter\let\csname xy\xyoption@@ version\endcsname=\next@
 \expandafter\let\expandafter\xyenddocmode@\csname DOCMODE\endcsname
 \expandafter\let\csname DOCMODE\endcsname\xyprovidedocmode@
 \xycatcodes
 \fi \ignorespaces}
\xydef@\xyendinput{\expandafter\let\csname DOCMODE\endcsname=\xyenddocmode@
 \message{loaded}\xyuncatcodes\endinput}
\expandafter\xylet@\expandafter\xyprovidedocmode@\csname DOCMODE\endcsname
\xylet@\xyenddocmode@=\relax
\xydef@\xydriversloaded@@{\do{unload}}
\xylet@\xydriversselected@@=\empty
\xylet@\xydriver@unload@support@@=\empty
\xydef@\selectdriver@#1{\DN@{#1}\edef\next@{\codeof\next@}%
 \expandafter\selectdriver@@\expandafter{\next@}}
\xydef@\selectdriver@single#1{\xysetup@@{\def\xydriversselected@@{\do{#1}}%
 \xyLoadDrivers@}\let\selectdriver@@=\changedriver@single}
\xydef@\changedriver@single#1{\xysetup@@{\def\xydriversselected@@{\do{#1}}%
 \xyReloadDrivers@}}
\xydef@\selectdriver@multiple#1{\expandafter\xysetup@@\expandafter{%
 \expandafter\def\expandafter\xydriversselected@@\expandafter{%
 \xydriversselected@@ \do{#1}}%
 \let\do=\activatedriver@ \xydriversselected@@}}
\xydef@\UseSingleDriver{\let\selectdriver@@=\selectdriver@single}
\xydef@\MultipleDrivers{\let\selectdriver@@=\selectdriver@multiple}
\xydef@\xyLoadDrivers@{\let\do=\activatedriver@ \xydriversselected@@}
\xydef@\xyReloadDrivers@{\activatedriver@{unload}\xyLoadDrivers@}
\xylet@\xyReloadDrivers=\xyReloadDrivers@
\xydef@\activatedriver@#1{%
 \let\doii=\activatedriversupport@ \csname xydriver@#1@support@@\endcsname}
\xydef@\activatedriversupport@#1#2{%
 \expandafter\ifx\csname xy#1loaded\endcsname\relax\DN@{}%
 \else\DN@{#2}\fi \next@}
\UseSingleDriver
\xydef@\xyselectoptionsupport@{\let\do=\activatedriver@ \xydriversselected@@}
\xydef@\xyShowDrivers{{\W@{Loaded:}\let\do=\doShow \xydriversloaded@@
 \let\next@=\empty
 \def\do##1{\ifx\next@\empty \DN@{##1}%
 \else \expandafter\DN@\expandafter{\next@, ##1}\fi}%
 \xydriversselected@@\W@{Selected: \next@.}}}
\def\doShow#1{\let\next@=\empty
 \def\doii##1##2{\ifx\next@\empty \DN@{##1}%
 \else \expandafter\DN@\expandafter{\next@, ##1}\fi}%
 \csname xydriver@#1@support@@\endcsname
 \W@{ <driver> #1 supports \next@.}}
\xydef@\newdriver#1{%
 \def\nextiii@##1{%
 \expandafter\def\expandafter\xydriversloaded@@
 \expandafter{\xydriversloaded@@\do{##1}}%
 \expandafter\let\csname xydriver@\xyoption@@ @support@@\endcsname=\empty}%
 \def\do##1{\DNii@{##1}\ifx\xyoption@@\nextii@ \let\nextiii@=\eat@ \fi}%
 \xydriversloaded@@ \expandafter\nextiii@\expandafter{\xyoption@@}%
 #1\relax
 \DN@##1{\xywithoption{##1}{%
 \selectdriver@{##1}\xyeveryrequest{##1}{\selectdriver@{##1}}}}%
 \expandafter\next@\expandafter{\xyoption@@}\ignorespaces}
\xydef@\xyaddsupport{\expandafter\xyadddriversupport@\expandafter{\xyoption@@}}
\xydef@\xyaddunsupport{\xyadddriversupport@{unload}}
\xydef@\xyadddriversupport@#1#2#3{%
 \DNii@{#1}\edef\nextii@{\codeof\nextii@}%
 \def\nextiii@{#2}\edef\nextiii@{\codeof\nextiii@}%
\def\next{\xybug@{<driver> \nextii@\space not loaded}}%
\def\do##1{\DN@{##1}\edef\next@{\codeof\next@}%
 \ifx\next@\nextii@ \let\next=\relax \fi}\xydriversloaded@@ \next
\def\next{\xybug@{<driver> \nextii@\space already supports \nextiii@}}%
\def\doii##1##2{\DN@{##1}\edef\next@{\codeof\next@}%
 \ifx\next@\nextiii@ \let\next=\relax \fi}\xydriversloaded@@ \next
 \DN@##1##2{\ifx##1\relax \let##1=\empty \fi
 \expandafter\def\expandafter##1\expandafter{##1\doii{##2}{#3}}}%
 \expandafter\expandafter\expandafter\next@
 \expandafter\expandafter\csname xydriver@\nextii@ @support@@\endcsname
 \expandafter{\nextiii@}%
 \DN@##1{\expandafter\xyeverywithoption\expandafter{\nextiii@}{%
 \xytestforsupport@{##1}}}%
 \expandafter\next@\expandafter{\nextii@}\xydriversloaded@@
 \ignorespaces}
\xydef@\xytestforsupport@#1{\def\do##1{\DN@{##1}\DNii@{#1}%
 \ifx\next@\nextii@ \expandafter\xyselectoptionsupport@ \fi}}
\xynew@{if}\ifunsupportwarnings@
\xydef@\xyunsupportwarning@#1#2{{%
 \DN@{#1}\edef\next@{\codeof\next@}
 \expandafter\ifx\csname xywarn@unload@\next@ @\endcsname\relax
 \expandafter\gdef\csname xywarn@unload@\next@ @\endcsname{}%
 \ifunsupportwarnings@ \xyclosedown@@\xyunsupportwarnings@@ \fi
 \global\unsupportwarnings@true
 \expandafter\gdef\expandafter\xyunsupportwarnings@@\expandafter{%
 \xyunsupportwarnings@@ \W@{ #2.}}%
 \W@{}%
 \W@{Xy-pic Warning: `\next@' reproduction is NOT EXACT\xytracelineno@:}%
 \W@{ #2.}%
 \W@{}%
 \fi}}
\xydef@\xyunsupportwarnings@@{\W@{}%
 \W@{Xy-pic Warning: The produced DVI file is NOT EXACT:}}
\xynew@{if}\ifsupportwarnings@
\xydef@\xysupportwarning@#1#2{{%
 \DN@{#1}\edef\next@{\codeof\next@}\DNii@{#2}\edef\nextii@{\codeof\nextii@}%
 \expandafter\ifx\csname xywarn@\next@ @\nextii@ @\endcsname\relax
 \expandafter\gdef\csname xywarn@\next@ @\nextii@ @\endcsname{}%
 \ifsupportwarnings@ \xyclosedown@@\xysupportwarnings@@ \fi
 \global\supportwarnings@true
 \expandafter\gdef\expandafter\xysupportwarnings@@\expandafter{%
 \xysupportwarnings@@ \driverextensioncomplain@{#1}{#2}}%
 \W@{}%
 \W@{Xy-pic Warning: The produced DVI file is NOT PORTABLE\xytracelineno@:}%
 \driverextensioncomplain@{#1}{#2}%
 \W@{}%
 \fi}}
\xydef@\xysupportwarnings@@{%
 \W@{Xy-pic Warning: The produced DVI file is NOT PORTABLE:}}
\xydef@\driverextensioncomplain@#1#2{%
 \DN@{#1}\edef\next@{\codeof\next@}\DNii@{#2}\edef\nextii@{\codeof\nextii@}%
 \W@{ It contains <driver> `\next@' \string\special s for the `\nextii@'
 extension.}}
\xydef@\dvimessage@#1#2{\xysupportwarning@{#1}{#2}}
\xynew@{if}\ifxydrivernoloads@
\xydef@\xydrivernoload@#1{\xyerror@{Could not load xy#1.tex}{}%
 \xydrivernoloads@true}
\xydef@\xydriverfail@#1{\xyerror@{Sorry, #1 not supported.}{}}
\xydef@\xyunload@#1{\xywarning@{Unloading #1.}}
\message{algorithms: directions,}
\xydef@\DirectionfromtheDirection@{\noexpand\Direction=\the\Direction
 \noexpand\d@X=\the\d@X \noexpand\d@Y=\the\d@Y
 \def\noexpand\sd@X{\sd@X}\def\noexpand\sd@Y{\sd@Y}%
 \noexpand\K@dXdY=\the\K@dXdY \noexpand\K@dYdX=\the\K@dYdX
 \chardef\noexpand\DirectionChar=\the\DirectionChar
 \chardef\noexpand\SemiDirectionChar=\the\SemiDirectionChar
 \def\noexpand\cosDirection{\cosDirection}%
 \def\noexpand\sinDirection{\sinDirection}%
 \noexpand\resetupDirection@}
\xydef@\Directiontest@@#1#2{#2}
\xydef@\setupDirection@{%
 \d@X=\X@c\advance\d@X-\X@p \d@Y=\Y@c\advance\d@Y-\Y@p
 \Directiontest@@\relax\setupDirection@i}
\xydef@\setupDirection@i{\DN@{\setupDirection@ii}%
 \ifdim\d@X=\d@Y
 \ifdim\zz@\d@Y \DN@{}%
 \else\ifdim\d@X<\z@ \DN@{\dlDirection@{-1.4142\d@X}}%
 \else \DN@{\urDirection@{1.4142\d@X}}\fi\fi
 \else\ifdim\d@X<\d@Y
 \ifdim\zz@\d@X \DN@{\uDirection@\d@Y}%
 \else\ifdim\zz@\d@Y \DN@{\lDirection@{-\d@X}}%
 \else\ifdim-\d@X=\d@Y \DN@{\ulDirection@{-1.4142\d@X}}\fi\fi\fi
 \else
 \ifdim\zz@\d@X \DN@{\dDirection@{-\d@Y}}%
 \else\ifdim\zz@\d@Y \DN@{\rDirection@\d@X}%
 \else\ifdim\d@X=-\d@Y \DN@{\drDirection@{1.4142\d@X}}\fi\fi\fi
 \fi\fi \next@}
\xydef@\dlDirection@{\Direction=\z@
 \def\cosDirection{-.7071}\def\sinDirection{-.7071}\def\sd@X{-}\def\sd@Y{-}%
 \chardef\DirectionChar=127\relax\chardef\SemiDirectionChar=127\relax
 \K@dXdY=1\K@ \K@dYdX=1\K@ \fixedDirection@}
\xydef@\dDirection@{\Direction=\K@
 \def\cosDirection{0}\def\sinDirection{-1}\def\sd@X{+}\def\sd@Y{-}%
 \chardef\DirectionChar=15\relax\chardef\SemiDirectionChar=31\relax
 \K@dXdY=\z@ \K@dYdX=\KK@\K@ \fixedDirection@}
\xydef@\drDirection@{\dimen@ii=2\K@ \Direction=\dimen@ii
 \def\cosDirection{+.7071}\def\sinDirection{-.7071}\def\sd@X{+}\def\sd@Y{-}%
 \chardef\DirectionChar=31\relax\chardef\SemiDirectionChar=63\relax
 \K@dXdY=-1\K@ \K@dYdX=-1\K@ \fixedDirection@}
\xydef@\rDirection@{\dimen@ii=3\K@ \Direction=\dimen@ii
 \def\cosDirection{+1}\def\sinDirection{0}\def\sd@X{+}\def\sd@Y{+}%
 \chardef\DirectionChar=47\relax\chardef\SemiDirectionChar=95\relax
 \K@dXdY=\KK@\K@ \K@dYdX=\z@ \fixedDirection@}
\xydef@\urDirection@{\dimen@ii=4\K@ \Direction=\dimen@ii
 \def\cosDirection{+.7071}\def\sinDirection{+.7071}\def\sd@X{+}\def\sd@Y{+}%
 \chardef\DirectionChar=63\relax\chardef\SemiDirectionChar=127\relax
 \K@dXdY=1\K@ \K@dYdX=1\K@ \fixedDirection@}
\xydef@\uDirection@{\dimen@ii=-3\K@ \Direction=\dimen@ii
 \def\cosDirection{0}\def\sinDirection{+1}\def\sd@X{+}\def\sd@Y{+}%
 \chardef\DirectionChar=79\relax\chardef\SemiDirectionChar=31\relax
 \K@dXdY=\z@ \K@dYdX=\KK@\K@ \fixedDirection@}
\xydef@\ulDirection@{\dimen@ii=-2\K@ \Direction=\dimen@ii
 \def\cosDirection{-.7071}\def\sinDirection{+.7071}\def\sd@X{-}\def\sd@Y{+}%
 \chardef\DirectionChar=95\relax\chardef\SemiDirectionChar=63\relax
 \K@dXdY=-1\K@ \K@dYdX=-1\K@ \fixedDirection@}
\xydef@\lDirection@{\Direction=-\K@
 \def\cosDirection{-1}\def\sinDirection{0}\def\sd@X{-}\def\sd@Y{+}%
 \chardef\DirectionChar=111\relax\chardef\SemiDirectionChar=95\relax
 \K@dXdY=\KK@\K@ \K@dYdX=\z@ \fixedDirection@}
\xydef@\fixedDirection@#1{\dimen@ii=#1\relax
 \d@X=\cosDirection\dimen@ii \d@Y=\sinDirection\dimen@ii
 \resetupDirection@}
\xydef@\setupDirection@ii{%
 \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
 \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
 \K@dXdY=\sd@X\d@X \ifdim\K@dXdY<500pt \multiply\K@dXdY\KK@ \fi \dimen@=\sd@Y\d@Y
 \advance\dimen@.5\KK@ \divide\dimen@\KK@
 \ifdim\dimen@=\z@\else
 \advance\K@dXdY by.5\dimen@\relax \divide\K@dXdY\dimen@
 \fi \K@dXdY=\sd@X\sd@Y\K@dXdY
 \K@dYdX=\sd@Y\d@Y \ifdim\K@dYdX<500pt \multiply\K@dYdX\KK@ \fi \dimen@=\sd@X\d@X
 \advance\dimen@.5\KK@ \divide\dimen@\KK@
 \ifdim\dimen@=\z@\else
 \advance\K@dYdX by.5\dimen@\relax \divide\K@dYdX\dimen@
 \fi \K@dYdX=\sd@X\sd@Y\K@dYdX
 \Direction=\maxdimen
 \ifnum\K@dXdY<-\K@ \else \ifnum\K@<\K@dXdY \else
 \ifdim \d@Y<\z@
 \Direction=\K@ \advance\Direction-\K@dXdY
 \else
 \Direction=\K@ \multiply\Direction-\thr@@ \advance\Direction-\K@dXdY
 \fi\fi\fi
 \ifnum-\K@<\K@dYdX \ifnum\K@dYdX<\K@
 \ifdim \d@X<\z@
 \Direction=-\K@ \advance\Direction\K@dYdX
 \else
 \Direction=\K@ \multiply\Direction\thr@@ \advance\Direction\K@dYdX
 \fi\fi\fi
 \ifnum\Direction=\maxdimen
 \Direction=\K@dYdX \advance\Direction-\K@dXdY \divide\Direction\tw@ 
 \ifnum\K@dXdY<\z@ \advance\Direction\K@ \advance\Direction\K@
 \else \advance\Direction-\K@ \advance\Direction-\K@ \fi
 \fi
 \imposeDirection@i
 \resetupDirection@
 }
\xydef@\imposeDirection@{\count@@=\Direction 
 \loop@\ifnum\count@@>4096 \advance\count@@-8192 \repeat@
 \loop@\ifnum\count@@<-4096 \advance\count@@8192 \repeat@
 \def\sd@X{+}\ifnum\count@@<\K@ \relax
 \ifnum\count@@>-3072 \def\sd@X{-}\fi\fi
 \def\sd@Y{+}\ifnum\count@@<3072 \relax
 \ifnum\count@@>-\K@ \relax\def\sd@Y{-}\fi\fi
 \imposeDirection@i
 \d@X=\cosDirection\xydashl@ \d@Y=\sinDirection\xydashl@
 \resetupDirection@}
\xydef@\imposeDirection@i{%
 \count@@=\K@ \multiply\count@@ by8 \advance\count@@\Direction
 \count@=\count@@ \advance\count@\KK@ \divide\count@64 \advance\count@\m@ne
 \loop@\ifnum127<\count@ \advance\count@-128 \repeat@
 \chardef\DirectionChar\count@
 \advance\count@@16 \divide\count@@\KK@ \advance\count@@\m@ne
 \loop@\ifnum127<\count@@ \advance\count@@-128 \repeat@
 \chardef\SemiDirectionChar\count@@
 \setbox8=\hbox{\xydashfont\SemiDirectionChar\/}%
 \quotient@@\cosDirection{\sd@X\wd8}\xydashl@
 \setbox8=\hbox{\xydashfont\count@=\SemiDirectionChar\advance\count@-64
 \ifnum\count@<\z@ \advance\count@128 \fi \char\count@\/}%
 \quotient@@\sinDirection{\sd@Y\wd8}\xydashl@}
\xydef@\getxyDirection@#1{\xy@@\bgroup\xy@@ix@{#1}%
 \xy@@{\expandafter\POS\the\toks9\relax\setupDirection@
 \edef\next@{\egroup \Direction=\the\Direction}\next@ \imposeDirection@ }}
\xydef@\reverseDirection@{%
 \d@X=-\d@X \d@Y=-\d@Y
 \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
 \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
 \dimen@=4\K@ \ifnum\Direction<\z@ \advance\Direction\dimen@
 \else \advance\Direction-\dimen@ \fi
 \count@=\DirectionChar \ifnum\count@<64 \advance\count@64
 \else \advance\count@-64 \fi \chardef\DirectionChar=\count@
 \edef\cosDirection{\if-\cosDirection\else-\cosDirection\fi}%
 \edef\sinDirection{\if-\sinDirection\else-\sinDirection\fi}%
 \resetupDirection@}
\xydef@\aboveDirection@#1{%
 \dimen@=\d@X \d@X=-\d@Y \d@Y=\dimen@
 \dimen@=\K@dXdY \K@dXdY=-\K@dYdX \K@dYdX=-\dimen@
 \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
 \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
 \dimen@=2\K@ \ifdim 1\Direction<\dimen@\else \dimen@=-6\K@ \fi
 \advance\Direction\dimen@
 \count@=\DirectionChar \ifnum\count@<96 \advance\count@32
 \else \advance\count@-96 \fi \chardef\DirectionChar=\count@
 \count@=\SemiDirectionChar \ifnum\count@<64 \advance\count@64
 \else \advance\count@-64 \fi \chardef\SemiDirectionChar=\count@
 \let\tmp@=\cosDirection
 \edef\cosDirection{\if-\sinDirection\else-\sinDirection\fi}%
 \let\sinDirection=\tmp@
 \dimen@=#1\relax \d@X=\cosDirection\dimen@ \d@Y=\sinDirection\dimen@
 \resetupDirection@}
\xydef@\belowDirection@#1{%
 \dimen@=\d@X \d@X=\d@Y \d@Y=-\dimen@
 \dimen@=\K@dXdY \K@dXdY=-\K@dYdX \K@dYdX=-\dimen@
 \ifdim\d@X<\z@ \def\sd@X{-}\else \def\sd@X{+}\fi
 \ifdim\d@Y<\z@ \def\sd@Y{-}\else \def\sd@Y{+}\fi
 \dimen@=-2\K@\ifdim 1\Direction<\dimen@\dimen@=6\K@\fi \advance\Direction\dimen@
 \count@=\DirectionChar \ifnum\count@<32 \advance\count@96
 \else \advance\count@-32 \fi \chardef\DirectionChar=\count@
 \count@=\SemiDirectionChar \ifnum\count@<64 \advance\count@64
 \else \advance\count@-64 \fi \chardef\SemiDirectionChar=\count@
 \let\tmp@=\sinDirection
 \edef\sinDirection{\if-\cosDirection\else-\cosDirection\fi}%
 \let\cosDirection=\tmp@
 \dimen@=#1\relax \d@X=\cosDirection\dimen@ \d@Y=\sinDirection\dimen@
 \resetupDirection@}
\xydef@\vDirection@(#1,#2)#3{\dimen@ii=#3\relax
 \dimen@=#1\dimen@ii \dimen@ii=#2\dimen@ii
 \d@X=\cosDirection\dimen@ \advance\d@X-\sinDirection\dimen@ii
 \d@Y=\sinDirection\dimen@ \advance\d@Y \cosDirection\dimen@ii
 \X@p=\X@c \advance\X@p-\d@X \Y@p=\Y@c \advance\Y@p-\d@Y
 \setupDirection@\ignorespaces}
\xydef@\resetDirection@{%
 \d@X=\X@c\advance\d@X-\X@p \d@Y=\Y@c\advance\d@Y-\Y@p \let\next@=\resetupDirection@
 \ifdim\sd@X\d@X<\z@ \let\next@=\setupDirection@i \fi
 \ifdim\sd@Y\d@Y<\z@ \let\next@=\setupDirection@i \fi
 \next@}
\xydef@\resetupDirection@{%
 \edef\Directiontest@@##1##2{\noexpand\DN@{##2}%
 \noexpand\ifdim\noexpand\d@X=\the\d@X\relax
 \noexpand\ifdim\noexpand\d@Y=\the\d@Y\relax \noexpand\DN@{##1}%
 \noexpand\fi\noexpand\fi \noexpand\next@}}
\xydef@\unsetupDirection@{\def\Directiontest@@##1##2{##2}}
\uDirection@\xydashl@
\message{edges,}
\xynew@{if}\ifInside@
\xydef@\zeroEdge#1{%
 \ifcase#1\relax \or \Inside@false \or \dimen@=\z@
 \or \else \Edge@c={\rectangleEdge}\fi}
\xydef@\circleEdge#1{\ifcase#1\expandafter\circleEdge@
 \or \expandafter\circleUnder@ \or \dimen@=\R@c
 \or \expandafter\circleProp@ \or \expandafter\circleInner@
 \else \expandafter\circleOuter@ \fi}
\xydef@\circleEdge@{\DN@{\ellipseEdge@}%
 \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
 \ifdim\R@c=\U@c\DN@{\circlecentredEdge@}%
 \else\DN@{\ellipsecentredEdge@}\fi
 \fi\fi \next@}
\xydef@\circleProp@{\DN@{\reverseDirection@\ellipseEdge@}%
 \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
 \ifdim\R@c=\U@c\DN@{\reverseDirection@\circlecentredEdge@}%
 \else\DN@{\reverseDirection@\ellipsecentredEdge@}\fi
 \fi\fi \next@}
\xydef@\circleUnder@{\Inside@false
 \ifdim\X@p=\X@c \relax \ifdim\Y@p=\Y@c \Inside@true \fi \fi 
 \ifInside@ \else \expandafter \circleCentre@ \fi}
\xydef@\circleCentre@{{%
 \ifdim\L@c=\R@c \relax\else
 \dimen@=\R@c\advance\dimen@-\L@c \divide\dimen@\tw@
 \advance\X@c\dimen@ \advance\R@c-\dimen@ \fi
 \d@X=\X@c \advance\d@X-\X@p \d@X=\ifdim\d@X<\z@-\fi\d@X
 \ifdim\U@c=\D@c\relax \else
 \dimen@=\U@c\advance\dimen@-\D@c \divide\dimen@\tw@
 \advance\Y@c\dimen@ \advance\U@c-\dimen@ \fi
 \d@Y=\Y@c \advance\d@Y-\Y@p \d@Y=\ifdim\d@Y<\z@-\fi\d@Y
 \DN@{}\ifdim\d@X>\R@c \relax \else \ifdim\d@Y>\U@c \relax 
 \else \ifdim\U@c=\R@c \DN@{\circlecentredUnder@}%
 \else \DN@{\ellipsecentredUnder@}\fi
 \fi\fi \next@}}
\xydef@\circleInner@{\DN@{\ellipseInner@}%
 \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
 \ifdim\R@c=\U@c\DN@{\circlecentredInner@}%
 \else\DN@{\ellipsecentredInner@}\fi
 \fi\fi \next@}
\xydef@\circleOuter@{\DN@{\ellipseOuter@}%
 \ifdim\R@c=\L@c\relax \ifdim\U@c=\D@c\relax
 \ifdim\R@c=\U@c\DN@{\circlecentredOuter@}%
 \else\DN@{\ellipsecentredOuter@}\fi
 \fi\fi \next@}
\xydef@\circlecentredEdge@{%
 \dimen@=-\cosDirection\R@c \advance\X@c\dimen@
 \dimen@=-\sinDirection\R@c \advance\Y@c\dimen@}
\xydef@\circlecentredUnder@{%
 \loop\ifdim\R@c>100\p@ \circlescale@ \repeat
 \edef\tmp@{\expandafter\removePT@\the\R@c}\dimen@=\tmp@\R@c 
 \edef\tmp@{\expandafter\removePT@\the\d@X}\advance\dimen@-\tmp@\d@X
 \edef\tmp@{\expandafter\removePT@\the\d@Y}\advance\dimen@-\tmp@\d@Y
 \ifdim\dimen@>\z@ \aftergroup\Inside@true \fi}
\xydef@\circlescale@{\divide\R@c\KK@ \divide\d@X\KK@ \divide\d@Y\KK@ }
\xydef@\circlecentredInner@{%
 \L@c=\sd@X\cosDirection\R@c \D@c=\sd@Y\sinDirection\R@c
 \R@c=\L@c \U@c=\D@c \Edge@c={\rectangleEdge}}
\xydef@\circlecentredOuter@{%
 \L@c=\R@c \D@c=\R@c \U@c=\D@c \Edge@c={\rectangleEdge}}
\xydef@\ellipsecentredEdge@{\bgroup \X@p=\X@c \Y@p=\Y@c 
 \ifdim\U@c>\R@c
 \X@c=\cosDirection\U@c \Y@c=\sinDirection\U@c
 \quotient@\tmp@\U@c\R@c \X@c=\tmp@\X@c \R@c=\U@c 
 \else
 \X@c=\cosDirection\R@c \Y@c=\sinDirection\R@c
 \quotient@\tmp@\R@c\U@c \Y@c=\tmp@\Y@c 
 \fi
 \advance\X@c\X@p \advance\Y@c\Y@p 
 \setupDirection@ \X@c=\X@p \Y@c=\Y@p \circlecentredEdge@
 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p 
 \ifdim\U@c>\L@c \quotient@\tmp@\L@c\U@c \d@X=\tmp@\d@X
 \else \quotient@\tmp@\U@c\R@c \d@Y =\tmp@\d@Y \fi
 \X@c=\X@p \advance\X@c\d@X \Y@c=\Y@p \advance\Y@c\d@Y 
 \edef\next@{\egroup \X@c=\the\X@c \Y@c=\the\Y@c}\next@ }%
\xydef@\ellipsecentredUnder@{%
 \ifdim\R@c>64\p@ \circlescale@ \divide\U@c\KK@ 
 \else \ifdim\U@c>64\p@ \circlescale@ \divide\U@c\KK@ \fi\fi
 \edef\tmp@{\expandafter\removePT@\the\R@c}\d@Y=\tmp@\d@Y 
 \edef\tmp@{\expandafter\removePT@\the\U@c}\d@X=\tmp@\d@X 
 \R@c=\tmp@\R@c \circlecentredUnder@ }
\xydef@\ellipsecentredOuter@{\Edge@c={\rectangleEdge}}
\xydef@\ellipsecentredInner@{%
 \bgroup \X@p=\X@c \Y@p=\Y@c \ellipsecentredEdge@
 \advance\X@c-\X@p \L@c=\ifdim\X@c<\z@-\fi\L@c
 \advance\Y@c-\Y@p \D@c=\ifdim\Y@c<\z@-\fi\D@c
 \edef\next@{\egroup \L@c=\the\L@c \D@c=\the\D@c}\next@
 \R@c=\L@c \U@c=\D@c \Edge@c={\rectangleEdge}}
\xydef@\ellipseEdge@{\bgroup
 \A@=\R@c \B@=\U@c
 \ifdim\R@c=\L@c \d@X=\z@ 
 \else \d@X=.5\R@c \advance\d@X-.5\L@c 
 \advance\A@\L@c \divide\A@\tw@ \fi
 \ifdim\U@c=\D@c \d@Y=\z@ 
 \else \d@Y=.5\U@c \advance\d@Y-.5\D@c 
 \advance\B@\D@c \divide\B@\tw@ \fi
 \bgroup
 \L@c=\A@ \U@c=\B@
 \R@p=\U@c \advance\R@p\L@c \multiply\R@p\tw@
 \ifdim\B@<\A@ \quotient@\tmp@\U@c\L@c \R@c=\tmp@\p@ \D@c=\p@
 \quotient@\tmp@\R@p\L@c \R@p=\tmp@\p@
 \else
 \ifdim\A@<\B@ \quotient@\tmp@\L@c\U@c \D@c=\tmp@\p@ \R@c=\p@
 \quotient@\tmp@\R@p\U@c \R@p=\tmp@\p@
 \else
 \R@c=\p@ \D@c=\p@ \quotient@\tmp@\R@p\U@c \R@p=\tmp@\p@
 \fi\fi
 \quotient@\sd@X\d@X\L@c \d@X=\sd@X\p@
 \quotient@\sd@Y\d@Y\U@c \d@Y=\sd@Y\p@
 \loop
 \bgroup \U@p=-\p@ \D@p=\z@
 \ifdim\R@c<\p@
 \edef\tmp@{\expandafter\removePT@\the\R@c}\dimen@=\tmp@\R@p 
 \advance\d@X\cosDirection\dimen@
 \else \advance\d@X\cosDirection\R@p \fi
 \edef\sd@X{\expandafter\removePT@\the\d@X}%
 \advance\U@p\sd@X\d@X
 \ifdim\R@c<\p@
 \edef\tmp@{\expandafter\removePT@\the\R@c}\dimen@=\tmp@\d@X 
 \advance\D@p\cosDirection\dimen@
 \else \advance\D@p\cosDirection\d@X \fi
 \ifdim\D@c<\p@
 \edef\tmp@{\expandafter\removePT@\the\D@c}\dimen@=\tmp@\R@p 
 \advance\d@Y\sinDirection\dimen@
 \else \advance\d@Y\sinDirection\R@p \fi
 \edef\sd@Y{\expandafter\removePT@\the\d@Y}%
 \advance\U@p\sd@Y\d@Y
 \ifdim\D@c<\p@
 \edef\tmp@{\expandafter\removePT@\the\D@c}\dimen@=\tmp@\d@Y 
 \advance\D@p\sinDirection\dimen@
 \else \advance\D@p\sinDirection\d@Y \fi
 \multiply\D@p\tw@ 
 \dimen@=\ifdim\U@p<\z@-\fi\U@p 
 \ifdim\dimen@<.01\p@ \U@p=\z@ 
 \else
 \quotient@\tmp@\U@p\D@p \U@p=\tmp@\p@
 \ifdim\U@p<\z@\xywarning@{poor convergence}\U@p=\z@
 \else \advance\R@p-\U@p \U@p=\ifdim\U@p<\z@-\fi\U@p 
 \fi \fi
 \edef\next@{\egroup \R@p=\the\R@p \U@p=\the\U@p \D@p=\the\D@p}\next@
 \ifdim\U@p>\z@ \repeat
 \edef\next@{\egroup \dimen@=\the\R@p}\next@
 \edef\tmp@{\expandafter\removePT@\the\dimen@}%
 \ifdim\B@<\A@ \dimen@=\tmp@\B@ \else \dimen@=\tmp@\A@ \fi
 \dimen@=-\dimen@
 \advance\X@c\cosDirection\dimen@
 \advance\Y@c\sinDirection\dimen@
 \edef\next@{\egroup \X@c=\the\X@c \Y@c=\the\Y@c}\next@ }%
\xydef@\ellipseOuter@{\Edge@c={\rectangleEdge}}
\xydef@\ellipseInner@{%
 \bgroup \X@p=\X@c \Y@p=\Y@c \ellipseEdge@
 \d@X=\X@c\advance\d@X-\X@p 
 \ifdim\d@X>\z@ \R@p=\d@X \L@p=\R@p 
 \ifdim\L@c=\R@c\else\advance\L@p\L@c \advance\L@p-\R@c \fi
 \else \L@p=-\d@X \R@p=\L@p 
 \ifdim\L@c=\R@c \else\advance\R@p\R@c \advance\R@p-\L@c \fi
 \fi
 \d@Y=\Y@c\advance\d@Y-\Y@p 
 \ifdim\d@Y>\z@ \U@p=\d@Y \D@p=\U@p 
 \ifdim\D@c=\U@c\else\advance\D@p\D@c \advance\D@p-\U@c \fi
 \else \D@p=-\d@X \R@p=\D@p 
 \ifdim\D@c=\U@c\else\advance\U@p\U@c \advance\U@p-\D@c \fi
 \fi 
 \edef\next@{\egroup
 \L@c=\the\L@p \D@c=\the\D@p \R@c=\the\R@p \U@c=\the\U@p}%
 \next@ \Edge@c={\rectangleEdge}}
\xydef@\rectangleEdge#1{\ifcase#1\expandafter\rectangleEdge@
 \or \expandafter\rectangleUnder@ \or \expandafter\rectangleDist@
 \or \expandafter\rectangleProp@
 \else \relax \fi}
\xydef@\rectangleEdge@{%
 \ifdim\d@Y<-.05\p@ \rectangleEdge@i
 \else\ifdim\d@Y<.05\p@ \rectangleEdge@ii
 \else \rectangleEdge@iii\fi\fi
 \resetupDirection@}
\xydef@\rectangleEdge@i{%
 \ifdim\d@X<-.05\p@ \settomin@\X@c+\R@c\U@c\d@X\d@Y \settomin@\Y@c+\U@c\R@c\d@Y\d@X%1a
 \else\ifdim\d@X<.05\p@ \advance\Y@c\U@c
 \else \settomin@\X@c-\L@c\U@c\d@X\d@Y \settomin@\Y@c+\U@c\L@c\d@Y\d@X
 \fi\fi}
\xydef@\rectangleEdge@ii{%
 \ifdim\d@X<-.05\p@ \advance\X@c\R@c
 \else\ifdim\d@X<.05\p@
 \else \advance\X@c-\L@c
 \fi\fi}
\xydef@\rectangleEdge@iii{%
 \ifdim\d@X<-.05\p@ \settomin@\X@c+\R@c\D@c\d@X\d@Y \settomin@\Y@c-\D@c\R@c\d@Y\d@X%3a
 \else\ifdim\d@X<.05\p@ \advance\Y@c-\D@c
 \else \settomin@\X@c-\L@c\D@c\d@X\d@Y \settomin@\Y@c-\D@c\L@c\d@Y\d@X
 \fi\fi}
\xydef@\settomin@#1#2#3#4#5#6{%
 \edef\nextii@{\A@=\the\A@ \B@=\the\B@}\quotient@\next@{#5}{#6}\nextii@
 \dimen@=\sd@X\sd@Y\next@#4\relax
 \ifdim#3<\dimen@ \dimen@=#3\fi \advance#1#2\dimen@}
\xydef@\rectangleUnder@{\Inside@false
 \ifdim\X@p=\X@c \ifdim\Y@p=\Y@c \Inside@true \fi\fi 
 \ifInside@ \else
 \dimen@=\X@p \advance\dimen@-\X@c 
 \ifdim \dimen@>-\L@c \relax \ifdim\dimen@<\R@c 
 \dimen@=\Y@p \advance\dimen@-\Y@c 
 \ifdim \dimen@>-\D@c \relax \ifdim\dimen@<\U@c 
 \Inside@true 
 \fi\fi\fi\fi\fi }
\xydef@\rectangleDist@{\let\next@=\rectangleDist@i
 \ifdim\d@X<-.05\p@ \dimen@=\R@c
 \else\ifdim\d@X<.05\p@ \dimen@=\z@ \DN@{\dimen@=\dimen@ii}%
 \else \dimen@=\L@c \fi\fi
 \ifdim\d@Y<-.05\p@ \dimen@ii=\U@c
 \else\ifdim\d@Y<.05\p@ \DN@{}%
 \else \dimen@ii=\D@c \fi\fi
 \next@}
\xydef@\rectangleDist@i{%
 \begingroup \quotient@\next\p@{\sd@X\cosDirection\p@}%
 \edef\next{\endgroup \dimen@=\next\dimen@}\next
 \begingroup \quotient@\next\p@{\sd@Y\sinDirection\p@}%
 \edef\next{\endgroup \dimen@ii=\the\dimen@ii}\next
 \ifdim\dimen@ii<\dimen@ \dimen@=\dimen@ii \fi}
\xydef@\rectangleProp@{%
 \enter@{\A@=\the\A@ \B@=\the\B@ \DirectionfromtheDirection@}%
 \reverseDirection@
 \dimen@=1\Direction \count@=\K@ \multiply\count@\tw@
 \ifnum \Direction>\count@
 \DN@{0}%
 \advance\dimen@-2\K@ \quotient@\nextii@{\dimen@}{2\K@}%
 \else\ifnum \Direction>\z@
 \dimen@=-\dimen@ \advance\dimen@2\K@ \quotient@\next@{\dimen@}{2\K@}%
 \DNii@{0}%
 \else\ifnum \Direction>-\count@
 \DN@{1}%
 \quotient@\nextii@{-\dimen@}{2\K@}%
 \else
 \advance\dimen@4\K@ \quotient@\next@{\dimen@}{2\K@}%
 \DNii@{1}%
 \fi\fi\fi
 \advance\X@c-\L@c \dimen@=\L@c \advance\dimen@\R@c 
 \ifdim\dimen@=\z@ \advance\X@c 2\L@c \else \advance\X@c\next@\dimen@ \fi
 \advance\Y@c+\U@c \dimen@=\D@c \advance\dimen@\U@c 
 \ifdim\dimen@=\z@ \advance\Y@c-2\U@c \advance\Y@c\Upness@\U@c
 \else \advance\Y@c-\nextii@\dimen@ \fi
 \leave@}
\message{connections;}
\xydef@\Creset@@{}
\xydef@\Cshavep@@{\noCshavep@@}
\xydef@\Cshavec@@{\noCshavec@@}
\xydef@\Cslidep@@{\noCslidep@@}
\xydef@\Cslidec@@{\noCslidec@@}
\xydef@\Calong@@{\noCalong@@}
\xydef@\noCshavep@@{\setupDirection@
 \enter@{\cfromthec@ \DirectionfromtheDirection@}%
 \reverseDirection@ \cfromp@ \the\Edge@c\z@
 \pfromc@ \leave@ \resetDirection@}
\xydef@\noCshavec@@{\setupDirection@ \the\Edge@c\z@ \resetDirection@}
\xydef@\noCslidep@@#1{\dimen@=#1\relax
 \advance\X@p\cosDirection\dimen@ \advance\Y@p\sinDirection\dimen@
 \resetDirection@}
\xydef@\noCslidec@@#1{\dimen@=#1\relax
 \advance\X@c\cosDirection\dimen@ \advance\Y@c\sinDirection\dimen@
 \resetDirection@}
\xydef@\noCalong@@#1{%
 \d@X=#1\d@X \d@Y=#1\d@Y \X@c=\X@p \Y@c=\Y@p \advance\X@c\d@X \advance\Y@c\d@Y
 \resetupDirection@}
\xydef@\Cintercept@@{\noCintercept@@}
\xydef@\noCintercept@@{\enter@{\pfromthep@}%
 \begingroup\Creset@@ \edef\tmp@{\endgroup
 \X@origin=\the\X@p \Y@origin=\the\Y@p \R@c=\the\d@X \U@c=\the\d@Y}\tmp@
 \loop@\dimen@=\ifdim\R@c<\z@-\fi\R@c \advance\dimen@\ifdim\U@c<\z@-\fi\U@c
 \ifdim\dimen@>10\p@ \advance\R@c \ifdim\R@c<\z@-\fi 16sp \divide\R@c\KK@ 
 \advance\U@c \ifdim\U@c<\z@-\fi 16sp \divide\U@c\KK@ \repeat@
 \intersect@ \leave@}
\xydef@\no@@{\setupDirection@
 \edef\Creset@@{\cfromthec@ \pfromthep@ \noexpand\setupDirection@}%
 \def\Cshavep@@{\noCshavep@@}\def\Cshavec@@{\noCshavec@@}%
 \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%
 \def\Calong@@{\noCalong@@}\def\Cintercept@@{\noCintercept@@}%
 \ifHidden@\else
 \ifdim\Y@c>\Y@max \Y@max=\Y@c \fi \ifdim\Y@p>\Y@max \Y@max=\Y@p \fi
 \ifdim\Y@c<\Y@min \Y@min=\Y@c \fi \ifdim\Y@p<\Y@min \Y@min=\Y@p \fi
 \ifdim\X@c>\X@max \X@max=\X@c \fi \ifdim\X@p>\X@max \X@max=\X@p \fi
 \ifdim\X@c<\X@min \X@min=\X@c \fi \ifdim\X@p<\X@min \X@min=\X@p \fi \fi}
\xydef@\Spread@@{}
\xydef@\checkoverlap@@{}
\xydef@\straight@#1{\setupDirection@ \def\Spread@@{#1}%
 \edef\Creset@@{\cfromthec@ \pfromthep@ \DirectionfromtheDirection@}%
 \DN@##1##2{\def\checkoverlap@@{%
 \ifdim##1\X@p>##1\X@c \let\next@=\relax \fi
 \ifdim##2\Y@p>##2\Y@c \let\next@=\relax \fi}}%
 \edef\nextii@{{\sd@X}{\sd@Y}}\expandafter\next@\nextii@
 \noCshavep@@\edef\Cshavep@@{\pfromthep@ \noexpand\resetDirection@}%
 \noCshavec@@\edef\Cshavec@@{\cfromthec@ \noexpand\resetDirection@}%
 \ifHidden@\else
 \ifdim\Y@c>\Y@max \Y@max=\Y@c \fi \ifdim\Y@p>\Y@max \Y@max=\Y@p \fi
 \ifdim\Y@c<\Y@min \Y@min=\Y@c \fi \ifdim\Y@p<\Y@min \Y@min=\Y@p \fi
 \ifdim\X@c>\X@max \X@max=\X@c \fi \ifdim\X@p>\X@max \X@max=\X@p \fi
 \ifdim\X@c<\X@min \X@min=\X@c \fi \ifdim\X@p<\X@min \X@min=\X@p \fi \fi
 \ifInvisible@\let\next@=\relax
 \else\ifdim 1\Direction<-2\K@ \let\next@=\straightv@
 \else\ifdim 1\Direction<\z@ \let\next@=\straighth@
 \else\ifdim 1\Direction<2\K@ \let\next@=\straightv@
 \else \let\next@=\straighth@ \fi\fi\fi\fi
 \checkoverlap@@ \next@
 \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%
 \def\Calong@@{\noCalong@@}\Creset@@}
\xydef@\straighth@{\setbox\z@=\hbox{%
 \A@=\wd\lastobjectbox@
 \B@=\dp\lastobjectbox@ \advance\B@\ht\lastobjectbox@
 \ifdim \A@=\z@ \count@@=\m@ne
 \else \dimen@=\sd@X\d@X \divide\dimen@\A@ \count@@=\dimen@ \fi
 \Spread@@
 \ifdim\d@X>\z@ \advance\X@c-\wd\lastobjectbox@ \fi
 \dimen@=-\sd@X\wd\lastobjectbox@
 \multiply\dimen@\K@dYdX \divide\dimen@\K@
 \ifdim\d@X>\z@ \advance\Y@c\dimen@ \advance\Y@c-\Leftness@\dimen@
 \else \advance\Y@c\Leftness@\dimen@ \fi
 \dimen@=\wd\lastobjectbox@ \A@=\sd@X\d@X \advance\A@-\dimen@
 \B@=\sd@X\dimen@ \multiply\B@\K@dYdX \divide\B@\K@
 \advance\B@-\d@Y \B@=\sd@Y\B@
 \count@=\count@@ \advance\count@\m@ne
 \ifnum\z@<\count@ \divide\A@\count@ \divide\B@\count@ \fi
 \A@=-\sd@X\A@ \B@=\sd@Y\B@ \wd\lastobjectbox@=\A@
 \kern\X@c \count@=\z@
 \loop@\ifnum\count@<\count@@ \advance\count@\@ne
 \raise\Y@c\copy\lastobjectbox@ \advance\Y@c\B@ \repeat@}%
 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}
\xydef@\straightv@{\setbox\z@=\vtop{%
 \A@=\wd\lastobjectbox@
 \B@=\dp\lastobjectbox@ \advance\B@\ht\lastobjectbox@
 \ifdim \B@=\z@ \count@@=\m@ne
 \else \dimen@=\sd@Y\d@Y \divide\dimen@\B@ \count@@=\dimen@ \fi
 \Spread@@
 \dimen@=\dp\lastobjectbox@ \advance\dimen@\ht\lastobjectbox@
 \B@=\sd@Y\d@Y \advance\B@-\dimen@
 \A@=\sd@Y\dimen@ \multiply\A@\K@dXdY \divide\A@\K@ \advance\A@-\d@X
 \A@=\sd@X\A@ \count@=\count@@ \advance\count@\m@ne
 \ifnum\z@<\count@ \divide\B@\count@ \divide\A@\count@ \fi
 \B@=\sd@Y\B@ \A@=\sd@X\A@ \ht\lastobjectbox@=\B@ \dp\lastobjectbox@=\z@
 \ifdim\d@Y<\z@ 
 \advance\Y@c\dimen@ \advance\Y@c\Upness@\B@
 \else
 \advance\dimen@\Upness@\B@ \advance\Y@c-\dimen@ \advance\Y@c\B@
 \fi
 \advance\Y@c\B@ 
 \ifdim\d@X<\z@ \else \advance\X@c-\wd\lastobjectbox@ \fi
 \null \kern-\Y@c \count@=\z@
 \loop@\ifnum\count@<\count@@ \advance\count@\@ne
 \nointerlineskip \moveright\X@c\copy\lastobjectbox@ \advance\X@c\A@
 \repeat@}%
 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}
\message{ Xy-pic loaded}\xyuncatcodes \endinput

xyall.tex
%% xyall.tex from $Id: xyall.doc,v 3.0 1995/07/07 20:14:21 kris Exp $
%%
%% Xy-pic ``All features'' option.
%% Copyright (c) 1993-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined \input xy \fi
\xyprovide{all}{All features}{\stripRCS$Revision: 3.0 $}%
 {Kristoffer H.~Rose}{kris@diku.dk}%
 {Computer Science, University of Copenhagen, Universitetsparken~1,
 DK--2100 K{\o}benhavn~{\O}}
\xyrequire{curve}
\xyrequire{frame}
\xyrequire{cmtip}
\xyrequire{line}
\xyrequire{rotate}
\xyrequire{color}
\xyrequire{matrix}
\xyrequire{arrow}
\xyrequire{graph}
\xyendinput

xyarrow.tex
%% xyarrow.tex from $Id: xyarrow.doc,v 3.2 1995/09/19 18:22:27 kris Exp kris $
%%
%% Xy-pic ``Arrows and Paths'' feature.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined \input xy \fi
\xyprovide{arrow}{Arrow and Path feature}{\stripRCS$Revision: 3.2 $}%
 {Kristoffer H.~Rose}{kris@diku.dk}%
 {Computer Science, University of Copenhagen, Universitetsparken~1,
 DK--2100 K{\o}benhavn~{\O}}
\message{path,}
\xydef@\PATH{\afterPATH{}}
\xylet@\afterPATH@=\empty
\xydef@\afterPATH#1{\save
 \DN@##1{\def\afterPATH@{\restore \def\afterPATH@{##1}#1}}%
 \expandafter\next@\expandafter{\afterPATH@}%
 \let\PATHfail@@=\empty
 \let\PATHnext@@=\empty
 \let\PATHevery@@=\empty
 \let\PATHlast@@=\empty
 \let\PATHeverysub@@=\empty
 \let\PATHbeforelabels@@=\empty
 \let\PATHafter@@=\empty
 \xy@{\afterPATH{#1}}{\def\PATHslide@@{\z@}}%
 \def\PATHcontinue@@{\xyFN@\PATH@}%
 \xyFN@\PATH@}
\xynew@{if}\ifPATHsingle@
\xydef@\PATH@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATH@}%
 \else\ifPATHsingle@ \let\next@=\PATH@single
 \else \let\next@=\PATH@normal \fi\fi \next@}
\xydef@\PATH@normal{%
 \ifx ~\next \DN@ ~{\xyFN@\PATHsetting@}%
 \else \addRQ@\ifx \next \addRQ@\DN@{\xy@'{}\xyFN@\PATHstraight@}%
 \else \addLQ@\ifx \next \addLQ@\DN@{\xy@`{}\xyFN@\PATHturn@}%
 \else\ifx \PATHfail@@\PATH@x \DN@{\xyFN@\PATHlast@}%
 \else
 \DNii@{\let\PATHfail@@=\PATH@x \xyFN@\PATH@}%
 \DN@{\expandafter\nextii@\PATHfail@@}%
 \fi\fi\fi\fi \next@}
\xylet@\PATHnext@@=\empty
\xylet@\PATHevery@@=\empty
\xylet@\PATHlast@@=\empty
\xylet@\PATHeverysub@@=\empty
\xylet@\PATHbeforelabels@@=\empty
\xylet@\PATHafter@@=\empty
\xylet@\PATHfail@@=\empty
\xydef@\PATHsetting@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHsetting@}%
 \else\ifx \bgroup\next
 \DN@##1{\xy@{~{##1}}{}\def\PATHfail@@{##1}\xyFN@\PATH@}%
 \else \addEQ@\ifx \next
 \addEQ@\DN@##1{\xy@{~={##1}}{}\def\PATHevery@@{##1}\xyFN@\PATH@}%
 \else \addLT@\ifx \next
 \addLT@\DN@##1{\xy@{~<{##1}}{}\def\PATHnext@@{##1}\xyFN@\PATH@}%
 \else \addGT@\ifx \next
 \addGT@\DN@##1{\xy@{~>{##1}}{}\def\PATHlast@@{##1}\xyFN@\PATH@}%
 \else \addDASH@\ifx \next
 \addDASH@\DN@##1{\xy@{~-{##1}}{}\def\PATHeverysub@@{##1}\xyFN@\PATH@}%
 \else \addPLUS@\ifx \next
 \addPLUS@\DN@##1{\xy@{~+{##1}}{}\def\PATHbeforelabels@@{##1}\xyFN@\PATH@}%
 \else \ifx /\next
 \DN@/##1{\xy@{~/{##1}}{}\def\PATHafter@@{##1}\xyFN@\PATH@}%
 \else
 \xyerror@{Unknown \string~ setting: \meaning\next}%
 {See the Xy-pic arrow feature documentation for help.}%
 \fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xylet@\PATHinit@@=\empty
\xylet@\PATHextra@@=\empty
\xylet@\PATHpost@@=\empty
\xylet@\PATHcontinue@@=\empty
\xydef@\PATHstraight@{%
 \def\PATHinit@@{\PATHinitstraight@}\def\PATHextra@@{}\def\PATHpost@@{}%
 \xy@@\pfromc@ \PATHafterPOS{\xyFN@\PATHsegment@}}
\xydef@\PATHlast@{%
 \def\PATHinit@@{\PATHinitstraight@}%
 \def\PATHextra@@{\let\PATHcontinue@@=\afterPATH@
 \addGT@\PATHaction@\PATHlast@@ \let\PATHlast@@=\empty}%
 \def\PATHpost@@{}%
 \xy@@\pfromc@ \PATHafterPOS{\xyFN@\PATHsegment@}}
\xydef@\PATHinitstraight@{\xy@@{\setupDirection@ \dimen@=\PATHslide@@
 \dimen@ii=-\sinDirection\dimen@
 \ifPATHomitslide@@\else\advance\X@p\dimen@ii\fi \advance\X@c\dimen@ii
 \dimen@ii= \cosDirection\dimen@
 \ifPATHomitslide@@\else\advance\Y@p\dimen@ii\fi \advance\Y@c\dimen@ii
 \PATHomitslide@@false \resetupDirection@}}
\xydef@\PATHslide@@{\z@}
\xynew@{if}\ifPATHomitslide@@
\xydef@\PATHsegment@{%
 \addLT@\ifx\next
 \addGT@{\addLT@\DN@##1}{%
 \xy@{<##1>}{\dimen@=##1\relax \edef\PATHslide@@{\the\dimen@}}%
 \xyFN@\PATHsegment@@}%
 \else \let\next@=\PATHsegment@@
 \fi \next@}
\xylet@\cfrominitial@@=\relax
\xylet@\cfromfinal@@=\relax
\xydef@\PATHsegment@@{\PATHinit@@ \resetbreaks
 \addEQ@\PATHaction@\PATHevery@@
 \addLT@\PATHaction@\PATHnext@@ \let\PATHnext@@=\empty
 \PATHextra@@
 \xy@@{\edef\cfrominitial@@{\cfromthep@}\edef\cfromfinal@@{\cfromthec@}%
 \edef\pfromlastbreak@@{\pfromthep@}}\resetbreaks%
 \def\subsegmentno@{0}\toks@={}%
 \expandafter\xyFN@\expandafter\PATHlabels@\PATHbeforelabels@@}
\xylet@\PATHlabelit@@=\empty
\xydef@\PATHlabels@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHlabels@}%
 \else \ifx ^\next 
 \DN@##1{\xy@^{}\let\PATHlabelit@@=\PATHlabelabove@@
 \DNii@{}\xyFN@\PATHanchor@}%
 \else \ifx _\next
 \DN@##1{\xy@_{}\let\PATHlabelit@@=\PATHlabelbelow@@
 \DNii@{}\xyFN@\PATHanchor@}%
 \else \ifx |\next
 \DN@##1{\xy@|{}\let\PATHlabelit@@=\PATHlabelbreak@\DNii@{}\xyFN@\PATHanchor@}%
 \else \let\next@=\PATHsubsegments@ \fi\fi\fi\fi \next@}
\xydef@\PATHanchor@{\begingroup \toks@={}\PATHanchor@i}
\xydef@\PATHanchor@i{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHanchor@i}%
 \else\addDASH@\ifx \next
 \addDASH@\DN@{\expandafter\addtotoks@\expandafter{\PATHanchor@toks}%
 \xyFN@\PATHanchor@i}%
 \else
 \DNii@##1{\endgroup\afterPLACE{\xyFN@\PATHit@}##1}%
 \DN@{\expandafter\nextii@\expandafter{\the\toks@}}%
 \fi\fi \next@}
{\xyuncatcodes \gdef\next{<>(.5)}}
\xylet@\PATHanchor@toks=\next
\xylet@\PATHitshapes@@=\empty
\xydef@\PATHit@{\let\PATHitshape@@=\empty \xyFN@\PATHit@i}
\xydef@\PATHit@i{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHit@i}%
 \else \ifx *\next \DN@*##1##{\PATHlabelit@@{!C##1}}%
 \else \addAT@\ifx\next \addAT@\DN@##1##{\PATHlabelit@@{\dir##1}}%
 \else \ifx [\next \DN@[##1]{%
 \expandafter\def\expandafter\PATHitshape@@\expandafter{\PATHitshape@@[##1]}%
 \xyFN@\PATHit@i}%
 \else \DN@{\PATHlabelit@@{}}%
 \fi\fi\fi\fi \next@}
\xydef@\PATHsubsegments@{\the\toks@
 \toks@={}\xy@@{\ifx\bstartPLACE@\relax\else\def\bendPLACE@{1}\fi
 \pfromlastbreak@@\cfromfinal@@\setupDirection@}%
 \addDASH@\PATHaction@\PATHeverysub@@
 \PATHpost@@ \PATHaction@/\PATHafter@@ \PATHcontinue@@}
\xydef@\PATHaction@default#1#2{\xy@{PATHaction#1{#2}}{}\POS#2\relax}
\xylet@\PATHaction=\PATHaction@default
\xydef@\PATHaction@#1#2{\expandafter\PATHaction\expandafter#1\expandafter{#2}}
\xylet@\PATHafterPOS@default=\afterPOS
\xylet@\PATHafterPOS=\PATHafterPOS@default
\xydef@\PATHlastout@@{3}
\xydef@\PATHturn@{\afterCIRorDIAG\PATHturn@cir\PATHturn@diag}
\xydef@\PATHturn@cir{\toks@={\xy@@{%
 \count@=\CIRin@@ \ifnum\count@<4\else\advance\count@-4\fi
 \count@@=\CIRout@@ \ifnum\count@@<4\else\advance\count@@-4\fi
 \ifnum\count@=\count@@ \xyerror@{<turn> cannot be half or full}{%
You asked for a <turn>ed segment with parallel in- and out-direction.^^J%
This is not allowed because it is not possible to position it uniquely.}\fi}}%
 \edef\next@{{\CIRin@@}{\expandafter\noexpand\CIRorient@@}{\CIRout@@}}%
 \expandafter\PATHturn@i\next@}
\xydef@\PATHturn@diag{\toks@={\xy@@{%
 \setupDirection@ \count@=\CIRin@@ \dimen@=\xydashl@ \ABfromdiag@
 \ifdim \sinDirection\A@>\cosDirection\B@ \def\CIRorient@@{\CIRacw@}%
 \advance\count@\ifnum\count@<6 \tw@ \else -6\fi
 \else \def\CIRorient@@{\CIRcw@}%
 \advance\count@\ifnum\count@>\@ne -\tw@ \else 6\fi
 \fi
 \edef\CIRout@@{\the\count@}}}%
 \edef\next@{{\CIRin@@}{}{}}%
 \expandafter\PATHturn@i\next@}
\xylet@\PATHpostpos@@=\empty
\xydef@\PATHturn@i#1#2#3{%
 \DN@##1{\def\PATHinit@@{\xy@@{%
 \def\CIRin@@{#1}\def\CIRorient@@{#2}\def\CIRout@@{#3}%
 \ifnum\CIRin@@=8 \let\CIRin@@=\PATHlastout@@ \fi
 \R@=\turnradius@
 ##1\relax}%
 \xy@@{\count@=\CIRin@@
 \ifPATHomitslide@@ \dimen@=-\PATHslide@@
 \ABfromdiag@ \advance\X@p-\B@ \advance\Y@p\A@ \fi
 \enter@{\pfromthep@ \basefromthebase@}}%
 \xy@@{\dimen@=\expandafter\ifx\CIRorient@@\CIRcw@-\fi\R@
 \ABfromdiag@ \advance\X@p-\B@ \advance\Y@p\A@
 \X@origin=\X@p \Y@origin=\Y@p}%
 \xy@@{\dimen@=\xydashl@ \ABfromdiag@ \R@c=\A@ \U@c=\B@
 \count@=\CIRout@@
 \dimen@=\expandafter\ifx\CIRorient@@\CIRcw@-\fi\R@
 \ABfromdiag@ \advance\X@c-\B@ \advance\Y@c\A@
 \dimen@=\xydashl@ \X@p=\X@c \Y@p=\Y@c
 \ABfromdiag@ \advance\X@p-\A@ \advance\Y@p-\B@
 \intersect@
 \count@=\CIRin@@ \dimen@=\p@ \ABfromdiag@}%
 \xy@@{\edef\next@{\expandafter\removePT@\the\A@}%
 \edef\nextii@{\expandafter\removePT@\the\B@}%
 \A@=\X@c \advance\A@-\X@origin \B@=\Y@c \advance\B@-\Y@origin
 \ifdim \next@\A@<-\nextii@\B@
 \dontleave@ \cfromp@
 \count@=\CIRin@@ \advance\count@\ifnum\count@<4 +4\else -4\fi
 \dimen@=\xydashl@ \Directionfromdiag@
 \the\Edge@c\z@
 \count@=\CIRin@@ \dimen@=\expandafter\ifx\CIRorient@@\CIRcw@-\fi\R@
 \ABfromdiag@ \advance\X@c-\B@ \advance\Y@c\A@
 \dimen@=5sp \ABfromdiag@ \advance\X@c\A@ \advance\Y@c\B@
 \fi
 \dimen@ii=\expandafter\ifx\CIRorient@@\CIRacw@-\fi\PATHslide@@
 \advance\R@\dimen@ii
 \drop@\literal@{\hbox\bgroup\cir@i}}%
 \xy@@{\X@p=\X@c \Y@p=\Y@c
 \count@=\CIRout@@
 \dimen@=\expandafter\ifx\CIRorient@@\CIRacw@-\fi\R@c
 \ABfromdiag@ \advance\X@p-\B@ \advance\Y@p\A@
 \edef\PATHpostpos@@{\X@c=\the\X@p \Y@c=\the\Y@p \noexpand\czeroEdge@
 \noexpand\PATHomitslide@@true}}%
 \xy@@{\count@=\CIRin@@
 \dimen@=\expandafter\ifx\CIRorient@@\CIRacw@-\fi\R@c
 \ABfromdiag@ \advance\X@c-\B@ \advance\Y@c\A@ \czeroEdge@}%
 \xy@@{\leave@
 \count@=\CIRin@@ \dimen@=\PATHslide@@
 \ABfromdiag@ \advance\X@p-\B@ \advance\Y@p\A@
 \edef\PATHlastout@@{\CIRout@@}%
 \count@=\CIRout@@ \dimen@=\xydashl@ \Directionfromdiag@}}}%
 \expandafter\next@\expandafter{\the\toks@}\toks@={}%
 \def\PATHextra@@{}%
 \def\PATHpost@@{\xy@@\PATHpostpos@@}%
 \xyFN@\PATHturn@ii}
\xydef@\PATHturn@ii{%
 \ifx /\next
 \DN@ /{\afterassignment\nextii@\dimen@=}%
 \DNii@{%
 \edef\next@{\noexpand\xy@@{\edef\noexpand\turnradius@{\the\dimen@}}}\next@
 \xy@@\pfromc@ \PATHafterPOS{\xyFN@\PATHsegment@}}%
 \else \DN@{\xy@@\pfromc@ \PATHafterPOS{\xyFN@\PATHsegment@}}\fi
 \next@}
\xydef@\ABfromdiag@{\ifcase\count@\relax
 \A@=-.7071\dimen@ \B@=-.7071\dimen@ \or \A@=\z@ \B@=-\dimen@
 \or \A@=+.7071\dimen@ \B@=-.7071\dimen@ \or \A@=\dimen@ \B@=\z@
 \or \A@=+.7071\dimen@ \B@=+.7071\dimen@ \or \A@=\z@ \B@=+\dimen@
 \or \A@=-.7071\dimen@ \B@=+.7071\dimen@ \or \A@=-\dimen@ \B@=\z@
 \else\xybug@{impossible <diag>?}\fi}
\xydef@\turnradius@{10pt}
\xydef@\turnradius{\afterADDOP{\Addop@@\turnradius@}}
\xydef@\PATHlabelabove@#1#2{\xy@@\save@ \droplabel@\belowDirection@{#1}{#2}%
 \xyFN@\PATHlabelalias@}
\xydef@\PATHlabelbelow@#1#2{\xy@@\save@ \droplabel@\aboveDirection@{#1}{#2}%
 \xyFN@\PATHlabelalias@}
\xylet@\PATHlabelabove@@=\PATHlabelabove@
\xylet@\PATHlabelbelow@@=\PATHlabelbelow@
\xydef@\droplabel@#1#2#3{\xy@@{\enter@\DirectionfromtheDirection@}%
 \DN@{#2}\ifx\next@\empty
 \expandafter\xy@@ix@\expandafter{\PATHitshape@@\labelbox{#3}}%
 \else \expandafter\xy@@ix@\expandafter{\PATHitshape@@#2{#3}}\fi
 \xy@@{\setbox\z@=\expandafter\object\the\toks9
 \advance\L@c\labelmargin@ \advance\R@c\labelmargin@
 \advance\D@c\labelmargin@ \advance\U@c\labelmargin@ 
 \setboxz@h{\kern\labelmargin@\boxz@\kern\labelmargin@}%
 \A@=\X@c \B@=\Y@c #1\xydashl@ \the\Edge@c\thr@@ 
 \advance\A@-\X@c \advance\B@-\Y@c \advance\X@c 2\A@ \advance\Y@c 2\B@
 \ht\z@=\U@c \dp\z@=\D@c \dimen@=\L@c \advance\dimen@\R@c \wd\z@=\dimen@ 
 \setbox\lastobjectbox@=\hbox{\X@c=\L@c \Y@c=\z@ \Drop@@}%
 \drop@{\box\lastobjectbox@}{}%
 \leave@}}
\xylet@\labelmargin@=\objectmargin@
\xydef@\labelmargin{\afterADDOP{\Addop@@\labelmargin@}}
\xydef@\hole{\hbox{\dimen@=\objectmargin@ \kern2\dimen@
 \vrule height\dimen@ depth\dimen@ width\z@}}
\xylet@\pfromlastbreak@@=\empty
\xylet@\breakcount@=\relax
\def\next{\cfrominitial@@}
\expandafter\let\csname cfrombreak0@\endcsname=\next
\xydef@\resetbreaks{%
 \xy@@{\let\bstartPLACE@=\relax \let\bendPLACE@=\relax}}
\xydef@\invisbreaks{\xy@@{\def\bstartPLACE@{}}}
\xydef@\initbreaks{\xy@@{\ifx\bstartPLACE@\relax
 \def\bstartPLACE@{0}\def\bendPLACE@{1}\fi}}
\xydef@\lastbreaks{\xy@@{\ifx\bstartPLACE@\relax
 \def\bstartPLACE@{0}\fi\def\bendPLACE@{1}}}
\xylet@\bstartPLACE@=\relax
\xylet@\bendPLACE@=\relax
\xydef@\PATHlabelbreak@#1#2{%
 \DN@{#1}\ifx\next@\empty \drop\labelbox{#2}%
 \else \drop#1{#2}\fi \xy@@{\save@}%
 \count@=\subsegmentno@ \advance\count@\@ne
 \edef\subsegmentno@{\the\count@}%
 \DN@##1##2##3##4{%
 \addtotoks@{%
 \xy@@{\ifx\bstartPLACE@\relax\def\bstartPLACE@{0}%
 \else\edef\bstartPLACE@{\bendPLACE@}\fi \def\bendPLACE@{##4}}}%
 \xy@@{\expandafter\edef\csname cmergebreak##1@\endcsname
 {\DirectionfromtheDirection@ \cfromthec@}%
 \expandafter\def\csname cfrombreak##3@\endcsname{\cfromfinal@@}%
 \expandafter\edef\csname cfrombreak##1@\endcsname
 {\DirectionfromtheDirection@ \cfromthec@}}%
 \addtotoks@{%
 \xy@@{\pfromlastbreak@@ 
 \csname cfrombreak##3@\endcsname
 \csname cmergebreak##1@\endcsname}%
 \addDASH@\PATHaction@\PATHeverysub@@
 \xy@@{\csname cfrombreak##2@\endcsname
 \csname cmergebreak##1@\endcsname 
 \edef\pfromlastbreak@@{\pfromthec@}\def\bstartPLACE@{##4}}}}%
 \count@@=\count@ \advance\count@\@ne \advance\count@@\m@ne
 \ifx\PLACEf@\empty 
 \edef\tmp@{{\subsegmentno@}{\the\count@@}{\the\count@}{}}%
 \else
 \edef\tmp@{{\subsegmentno@}{\the\count@@}{\the\count@}\PLACEf@}%
 \fi \expandafter\next@\tmp@
 \xyFN@\PATHlabelalias@}
\xydef@\infinitize@#1{\the\Edge@c4%
 \dimen@=\X@c \advance\dimen@-\X@p
 \def\next{TT}%
 \DN@{\zeroEdge}\expandafter\DNii@\expandafter{\the\Edge@c}%
 \ifx\next@\nextii@ \def\next{TF}\fi
 \if\next
 \ifdim\dimen@<\z@ \L@c=\X@c \advance\L@c-\X@min \advance\L@c1pc
 \else \ifdim\dimen@>\z@ \R@c=\X@max \advance\R@c-\X@c \advance\R@c1pc \fi\fi
 \dimen@=\Y@c \advance\dimen@-\Y@p
 \ifdim\dimen@<\z@ \D@c=\Y@c \advance\D@c-\Y@min \advance\D@c1pc
 \else\ifdim\dimen@>\z@ \U@c=\Y@max \advance\U@c-\Y@c \advance\U@c1pc \fi\fi
 \Edge@c={\rectangleEdge}\fi \let\next=\relax}
\xylet@\labelstyle=\scriptstyle
\xydef@\labelbox#1{\hbox{$\m@th\labelstyle{#1}$}}
\xydef@\PATHlabelalias@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\PATHlabelalias@}%
 \else \addEQ@\ifx \next
 \addEQ@\DN@"##1"{\savealias@{##1}\xyFN@\PATHlabelalias@}%
 \else \DN@{\xy@@\leave@ \PATHlabels@}\fi\fi \next@}
{\xyuncatcodes \gdef\next#1{\POS!C="#1"\relax}}
\xylet@\savealias@=\next
\message{\string\ar,}
\xylet@\arvariant@@=\empty
\xylet@\arstemprefix@@=\empty
\xylet@\artail@@=\empty
\xylet@\arstem@@=\empty
\xylet@\arhead@@=\empty
\xylet@\armodifiers@@=\empty
\xylet@\arlabels@@=\empty
\xylet@\arafterPOS@@=\empty
\xylet@\arinit@@=\empty
\xylet@\arexit@@=\empty
\xylet@\arcomponent@@=\relax
\xylet@\arcomponenttype@@=\relax
\xylet@\afterar@@=\relax
\xydef@\ar{\relax\arSAFE}
\xydef@\arSAFE{%
 \let\arvariant@@=\empty
 \def\arstemprefix@@{\dir}%
 \def\artail@@{ {}}%
 \edef\arstem@@{\arvariant@@{-}}%
 \edef\arhead@@{\arvariant@@{>}}%
 \def\armodifiers@@{}%
 \def\arafterPOS@@{}%
 \def\arlabels@@{}%
 \def\arinit@@{}%
 \def\arexit@@{}%
 \let\PATHlabelabove@@=\PATHlabelabove@
 \let\PATHlabelbelow@@=\PATHlabelbelow@
 \xyFN@\ar@}
\xydef@\ar@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\ar@}%
 \else \addAT@\ifx\next \addAT@\DN@{\xyFN@\ar@form}%
 \else\ifx |\next
 \DN@ |{\ar@anchor|}%
 \else\ifx ^\next
 \DN@ ^{\ar@anchor^}%
 \else\ifx _\next
 \DN@ _{\ar@anchor_}%
 \else \let\next@=\ar@x \fi\fi\fi\fi\fi \next@}
\xydef@\addtoarinit@#1{%
 \expandafter\def\expandafter\arinit@@\expandafter{\arinit@@ #1}}
\xydef@\addtoarlabels@#1{%
 \expandafter\def\expandafter\arlabels@@\expandafter{\arlabels@@ #1}}
\xydef@\ar@anchor#1{\begingroup
 \def\PATHlabelit@@##1##2{%
 \DN@{##1}\ifx\next@\empty
 \DN@####1{\expandafter\endgroup\expandafter\addtoarlabels@
 \expandafter{\the\toks@####1{##2}}\xyFN@\ar@}%
 \else
 \DN@####1{\expandafter\endgroup\expandafter\addtoarlabels@
 \expandafter{\the\toks@*!C####1##1{##2}}\xyFN@\ar@}\fi
 \expandafter\next@\expandafter{\PATHitshape@@}}%
 \toks@={#1}%
 \def\xy@##1##2{\addtotoks@{##1}}\let\oxy@=\xy@ \let\xy@@ix@=\eat@
 \DNii@{}\xyFN@\PATHanchor@}
\xydef@\ar@form{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\ar@form}%
 \else\ifx ^\next \DN@ ^{\xyFN@\ar@style}\edef\arvariant@@{\string^}%
 \else\ifx _\next \DN@ _{\xyFN@\ar@style}\edef\arvariant@@{\string_}%
 \else\ifx 0\next \DN@ 0{\xyFN@\ar@style}\def\arvariant@@{0}%
 \else\ifx 1\next \DN@ 1{\xyFN@\ar@style}\def\arvariant@@{1}%
 \else\ifx 2\next \DN@ 2{\xyFN@\ar@style}\def\arvariant@@{2}%
 \else\ifx 3\next \DN@ 3{\xyFN@\ar@style}\def\arvariant@@{3}%
 \else\ifx \bgroup\next \let\next@=\ar@style
 \else\ifx [\next \DN@[##1]{\ar@modifiers{[##1]}}%
 \else\ifx *\next \DN@ *{\ar@modifiers}%
 \else\addLT@\ifx\next \let\next@=\ar@slide
 \else\ifx /\next \let\next@=\ar@curveslash
 \else\ifx (\next \let\next@=\ar@curveinout
 \else\addRQ@\ifx\next \addRQ@\DN@{\ar@curve@}%
 \else\addLQ@\ifx\next \addLQ@\DN@{\xyFN@\ar@curve}%
 \else\addDASH@\ifx\next \addDASH@\DN@{\defarstem@-\xyFN@\ar@}%
 \else\addEQ@\ifx\next \addEQ@\DN@{\def\arvariant@@{2}\defarstem@-\xyFN@\ar@}%
 \else\addDOT@\ifx\next \addDOT@\DN@{\defarstem@.\xyFN@\ar@}%
 \else\ifx :\next \DN@:{\def\arvariant@@{2}\defarstem@.\xyFN@\ar@}%
 \else\ifx ~\next \DN@~{\defarstem@~\xyFN@\ar@}%
 \else\ifx !\next \DN@!{\dasharstem@\xyFN@\ar@}%
 \else\ifx ?\next \DN@?{\ar@upsidedown\xyFN@\ar@}%
 \else \let\next@=\ar@error
 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xydef@\defarstem@#1{\edef\arstem@@{\arvariant@@{\string#1}}%
 \DNii@##1##{\next@}%
 \edef\next@##1{\def\noexpand\artail@@{\arvariant@@{##1}}}%
 \expandafter\nextii@\artail@@
 \edef\next@##1{\def\noexpand\arhead@@{\arvariant@@{##1}}}%
 \expandafter\nextii@\arhead@@}
\xydef@\dasharstem@{%
 \DN@##1##{\nextii@{##1}}\DNii@##1##2{\def\arstem@@{##1{##2##2}}}%
 \expandafter\next@\arstem@@}
\xydef@\ar@error#1{\xyerror@{Illegal <form>ation (\meaning\next)}{}%
 \xyFN@\ar@}
\xydef@\ar@style{%
 \ifx \bgroup\next \def\artail@@{{}}%
 \edef\arstem@@{\arvariant@@{-}}\edef\arhead@@{\arvariant@@{>}}%
 \expandafter\ar@i
 \else \resetvariant@\artail@@ \resetvariant@\arstem@@ \resetvariant@\arhead@@
 \expandafter\xyFN@\expandafter\ar@ \fi}
\xydef@\resetvariant@#1{%
 \def\next@##1##{\expandafter\nextii@\expandafter{\arvariant@@}}%
 \DNii@##1##2{\def#1{##1{##2}}}%
 \expandafter\next@#1}
\xydef@\ar@i#1{\DN@{#1}%
 \ifx\next@\empty \edef\arstem@@{\arvariant@@{}}\edef\arhead@@{\arvariant@@{}}%
 \DN@{\xyFN@\ar@}%
 \else
 \let\arcomponent@@=\ar@ii \let\arcomponenttype@@=\artip@
 \DN@{\xyFN@\arcomponent@#1$}%
 \fi \next@}
\xydef@\ar@ii{\ifx $\next \let\next@=\ar@iv
 \else \expandafter\def\expandafter\artail@@\expandafter{\the\toks@}%
 \let\arcomponent@@=\ar@iii \let\arcomponenttype@@=\arconn@
 \DN@{\xyFN@\arcomponent@}\fi \next@}
\xydef@\ar@iii{%
 \expandafter\def\expandafter\arstem@@\expandafter{\the\toks@}%
 \let\arcomponent@@=\ar@iv \let\arcomponenttype@@=\artip@
 \xyFN@\arcomponent@}
\xydef@\ar@iv{%
 \expandafter\def\expandafter\arhead@@\expandafter{\the\toks@}%
 \ifx $\next \DN@ ${\xyFN@\ar@}%
 \else \xyerror@{illegal <arrow>: \meaning\next\space not valid}{}\fi \next@}
\xydef@\ar@x{%
 \let\PATHlabelbreak@@=\arlabelbreak@
 \let\arsavedPATHafterPOS@@=\PATHafterPOS \let\PATHafterPOS=\arafterPOS@
 \toks@={\ar@PATH}%
 \expandafter\addtotoks@\expandafter{\expandafter{\artail@@}}%
 \expandafter\addtotoks@\expandafter{\expandafter{\arstem@@}}%
 \expandafter\addtotoks@\expandafter{\expandafter{\arstemprefix@@}}%
 \expandafter\addtotoks@\expandafter{\expandafter{\arhead@@}}%
 \expandafter\addtotoks@\expandafter{\expandafter{\armodifiers@@}}%
 \expandafter\addtotoks@\expandafter{\expandafter{\arinit@@}}%
 \expandafter\addtotoks@\expandafter{\expandafter{\arexit@@}}%
 \expandafter\addtotoks@\expandafter{\expandafter{\arlabels@@}}%
 \addtotoks@{\afterar@@}%
 \expandafter\DNii@\expandafter{\the\toks@}\toks@={}%
 \nextii@}
{\xyuncatcodes \gdef\next#1#2#3#4#5#6#7#8#9{%
 \afterPATH{#9}%
 ~={#6\invisbreaks\connect i#5#3{}\resetbreaks}%
 ~<{\arsegment{?<*#5\dir#1}0}%
 ~>{\arsegment{?>*#5\dir#4}1}%
 ~-{\initbreaks\connect #5#3#2}%
 ~/{#7}%
 ~+{#8}}}
\xylet@\ar@PATH=\next
\xydef@\arafterPOS@#1{%
 \arsavedPATHafterPOS@@{\let\PATHafterPOS=\arsavedPATHafterPOS@@
 \DN@{#1}\expandafter\next@\arafterPOS@@}}%
\xylet@\arsavedPATHafterPOS@@=\relax
\xylet@\artmp@@=\relax
\xydef@\arsegment#1#2{\xy@@{\enter@\cfromthec@}%
 \POS#1\relax
 \xy@@{\edef\tmp@{\cmergethecz@}\leave@}%
 \ifcase#2\xy@@{\setupDirection@ \swap@ \tmp@ \infinitize@-\swap@}%
 \else \xy@@{\tmp@ \setupDirection@ \infinitize@+}\fi}
\xydef@\cmergethecz@{\noexpand\cmergez@
 {\the\Y@c}{\the\X@c}{\the\D@c}{\the\U@c}{\the\L@c}{\the\R@c}}
\xydef@\cmergethepz@{\noexpand\cmergez@
 {\the\Y@p}{\the\X@p}{\the\D@p}{\the\U@p}{\the\L@p}{\the\R@p}}
\xydef@\cmergez@#1#2#3#4#5#6{\A@=#2\relax \B@=#1\relax 
 \dimen@=\X@c \advance\dimen@-\A@ \advance\dimen@#5\relax 
 \ifdim\dimen@>\z@ \L@c=\dimen@\fi
 \dimen@=\A@ \advance\dimen@-\X@c \advance\dimen@#6\relax 
 \ifdim\dimen@>\z@ \R@c=\dimen@\fi
 \dimen@=\Y@c \advance\dimen@-\B@ \advance\dimen@#3\relax 
 \ifdim\dimen@>\z@ \D@c=\dimen@ \fi
 \dimen@=\B@ \advance\dimen@-\Y@c \advance\dimen@#4\relax 
 \ifdim\dimen@>\z@ \U@c=\dimen@\fi
 \Edge@c={\rectangleEdge}}
\xydef@\arcomponent@{%
 \ifx ^\next \toks@ii={^}\DN@ ^{\xyFN@\arcomponent@i}%
 \else\ifx _\next \toks@ii={_}\DN@ _{\xyFN@\arcomponent@i}%
 \else\ifx 1\next \toks@ii={1}\DN@ 1{\xyFN@\arcomponent@i}%
 \else\ifx 2\next \toks@ii={2}\DN@ 2{\xyFN@\arcomponent@i}%
 \else\ifx 3\next \toks@ii={3}\DN@ 3{\xyFN@\arcomponent@i}%
 \else\ifx \bgroup\next \expandafter\toks@ii\expandafter{\arvariant@@}%
 \let\next@=\arcomponent@i
 \else\ifx *\next \DN@*##1##{\arcomponent@ii{##1}}%
 \else \expandafter\toks@ii\expandafter{\arvariant@@}\toks@={}%
 \let\next@=\arcomponenttype@@
 \fi\fi\fi\fi\fi\fi\fi
 \next@}
\xydef@\arcomponent@i#1{\toks@={#1}\arcomponent@x}
\xydef@\arcomponent@ii#1#2{\toks@={*#1{#2}}\xyFN@\arcomponent@@}
\xydef@\artip@{%
 \addGT@\ifx\next \addGT@\addtotoks@ \addGT@\DN@{\xyFN@\artip@}%
 \else\addLT@\ifx\next \addLT@\addtotoks@ \addLT@\DN@{\xyFN@\artip@}%
 \else\ifx (\next \addtotoks@(\DN@({\xyFN@\artip@}%
 \else\ifx )\next \addtotoks@)\DN@){\xyFN@\artip@}%
 \else\ifx |\next \addtotoks@|\DN@|{\xyFN@\artip@}%
 \else\addLQ@\ifx\next \addLQ@\addtotoks@ \addLQ@\DN@{\xyFN@\artip@}%
 \else\addRQ@\ifx\next \addRQ@\addtotoks@ \addRQ@\DN@{\xyFN@\artip@}%
 \else\addPLUS@\ifx \next \addPLUS@\addtotoks@ \addPLUS@\DN@{\xyFN@\artip@}%
 \else\ifx /\next \addtotoks@/\DN@/{\xyFN@\artip@}%
 \else\ifcat A\noexpand\next \DN@##1{\addtotoks@{##1}\xyFN@\artip@}%
 \else\ifx\space@\next \addtotoks@{ }\expandafter\DN@\space{\xyFN@\artip@}%
 \else \let\next@=\arcomponent@x
 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xydef@\arconn@{%
 \addDASH@\ifx\next \addDASH@\addtotoks@ \addDASH@\DN@{\xyFN@\arconn@}%
 \else\addEQ@\ifx\next \addEQ@\addtotoks@ \addEQ@\DN@{\xyFN@\arconn@}%
 \ifx\arvariant@@\empty \def\arvariant@@{2}\fi
 \else\addDOT@\ifx\next \addDOT@\addtotoks@ \addDOT@\DN@{\xyFN@\arconn@}%
 \else\ifx :\next \addtotoks@:\DN@:{\xyFN@\arconn@}%
 \ifx\arvariant@@\empty \def\arvariant@@{2}\fi
 \else\ifx ~\next \addtotoks@~\DN@~{\xyFN@\arconn@}%
 \else \let\next@=\arcomponent@x
 \fi\fi\fi\fi\fi \next@}
\xydef@\arcomponent@x{%
 \DN@##1{\toks@=\expandafter{\the\toks@ii{##1}}}%
 \expandafter\next@\expandafter{\the\toks@}%
 \xyFN@\arcomponent@@}
\xydef@\ar@curveslash/#1/{\expandafter\ar@curve@\ar@slashing{#1}}
\xydef@\ar@slashing#1{{\xy@{**{} ?+/#1/+/#1/ @+c}{\setupDirection@
 \vfromslide@{#1}%
 \X@c=2\X@c \advance\X@c\X@p \advance\X@c.5\d@X
 \Y@c=2\Y@c \advance\Y@c\Y@p \advance\Y@c.5\d@Y
 \czeroEdge@
 \spushc@}}}
{\xyuncatcodes \catcode`\#=6
 \gdef\next(#1,#2){{+/#1 3pc/,p+/#2 3pc/}}}
\xylet@\ar@curveinout@=\next
\xydef@\ar@curveinout{\expandafter\ar@curve@load\ar@curveinout@}
\xydef@\ar@curve{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\ar@curve}%
 \else\ifx \bgroup\next \let\next@=\ar@curve@load
 \else\ifx "\next \DN@"##1"{\ar@curve@{"##1"}}%
 \else \xyerror@{@= <form> must be followed by \string"<id>\string" or
 {<control point list>}}{}%
 \fi\fi\fi \next@}
{\xyuncatcodes \gdef\next#1#2{\def#1##1{#2{;@={##1}}}}}
\next\ar@curve@load\ar@curve@
\xydef@\ar@curve@#1{\curve@check
 \setcurvearinit@{#1}\setcurvearexit@\arexit@@
 \def\arstemprefix@@{\crvs}\xyFN@\ar@}
{\xyuncatcodes \gdef\next#1{\save @(,#1\restore}}
\xylet@\setcurvearinit@i=\next
\xydef@\setcurvearinit@#1{%
 \expandafter\addtoarinit@\expandafter{\setcurvearinit@i{#1}}}
{\xyuncatcodes \gdef\next#1{\def#1{\POS @i @) }}}
\xylet@\setcurvearexit@=\next
\xydef@\curve@check{%
 \xyerror@{Forms @/.../, @(...), and @`{...}, only available when curve
 extension loaded}{}}
\xywithoption{curve}{\let\curve@check=\relax}
\xydef@\ar@modifiers#1{%
 \expandafter\def\expandafter\armodifiers@@\expandafter{\armodifiers@@#1}%
 \xyFN@\ar@}
{\xyuncatcodes \catcode`\#=6 \catcode`\@=11
 \gdef\next<#1>{\def\arafterPOS@@{<#1>}\xyFN@\ar@}}
\xylet@\ar@slide=\next
\xydef@\ar@upsidedown{\let\next=\PATHlabelabove@@
 \let\PATHlabelabove@@=\PATHlabelbelow@@ \let\PATHlabelbelow@@=\next}
\xyendinput

xycmtip.tex
%% xycmtip.tex from $Id: xycmtip.doc,v 3.1 1995/09/05 20:31:32 kris Exp $
%%
%% Xy-pic ``Computer Modern tips'' option.
%% Copyright (c) 1992-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined \input xy \fi
\xyprovide{cmtip}{Computer Modern tip extension}{\stripRCS$Revision: 3.1 $}%
 {Kristoffer H.~Rose}{kris@diku.dk}%
 {Computer Science, University of Copenhagen, Universitetsparken~1,
 DK--2100 K{\o}benhavn~{\O}}
\xyfont@\xycmatfont=xycmat10
\xyfont@\xycmbtfont=xycmbt10
\xylet@\xytip@=\tip@
\xylet@\xyatip@=\atip@
\xylet@\xybtip@=\btip@
\xylet@\xytipjot@=\tipjot@
\xydef@\xycm@{\let\xyatipfont=\xycmatfont \let\xybtipfont=\xycmbtfont}
\xydef@\cmtip@{\xycm@@ \tip@x\tip@@}
\xydef@\cmatip@{\xycm@@ \tip@x\atip@@}
\xydef@\cmbtip@{\xycm@@ \tip@x\btip@@}
\xydef@\xycm@@{\xycm@}
\xydef@\xycmtip@unload{\def\xycm@@{\xycm@}}
\xyaddunsupport{cmtip}\xycmtip@unload
\xydef@\UseComputerModernTips{\def\tipjot@{.66\jot}%
 \let\tip@=\cmtip@ \let\atip@=\cmatip@ \let\btip@=\cmbtip@}
\xydef@\NoComputerModernTips{\let\tipjot@=\xytipjot@
 \let\tip@=\xytip@ \let\atip@=\xyatip@ \let\btip@=\xybtip@}
\xyendinput

xycolor.tex
%% xycolor.tex from $Id: xycolor.doc,v 3.2 1995/09/19 18:20:20 ross Exp ross $
%%
%% Xy-pic ``Colour extension'' option.
%% Copyright (c) 1993-1995 Ross Moore <ross@mpce.mq.edu.au>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined \input xy \fi
\xyprovide{color}{Colour extension}{\stripRCS$Revision: 3.2 $}%
 {Ross Moore}{ross@mpce.mq.edu.au}%
 {Mathematics Department, Macquarie University, NSW~2109, Australia}
\xydef@\xycolorwarning@@{\xycolormessage@
 \gdef\xycolorwarning@@{\xycolormessage@
 \xywarning@{...no further colour warnings will be given.}%
 \global\let\xycolorwarning@@=\relax }}
\xylet@\xycolorwarning@=\xycolorwarning@@
\xydef@\xycolormessage@{%
 \xywarning@{Current driver does not support colour.}}%
\xydef@\xyNoColor@#1{}
\xylet@\xycolor@@=\xyNoColor@
\xydef@\xyNoColor@@#1#2{\xycolorwarning@}
\xydef@\xycolor@{\xycolor@@}
\xylet@\xylocalColor@=\xyNoColor@@
\xydef@\UnloadColor@{%
 \let\xylocalColor@=\xyNoColor@@
 \let\xycolor@@=\xyNoColor@
 \let\xycolorwarning@=\xycolorwarning@@ }
\xylet@\UnloadColor@@=\UnloadColor@
\xyaddunsupport{color}{\UnloadColor@@\relax}
\ifx\current@color\undefined \xydef@\xybasecolor@{}%
\else \def\xybasecolor@{\current@color}\fi
\xydef@\xystackcolor@{\bgroup \DN@##1##2{\egroup}%
 \ifInvisible@\else\ifHidden@\else\DNii@{\no@@}\ifx\nextii@\Connect@@ 
 \else\DN@{\xystackcolor@i}\fi\fi\fi \next@ } 
\xydef@\xystackcolor@i#1#2{\checkXyStyle@ 
 \DN@{#2}\ifx\next@\empty
 \def\tmp@##1{\DN@{\xycolor@push{#1}##1\xycolor@pop}}%
 \else\def\tmp@##1{\DN@{\xycolor@push{#2 #1}##1\xycolor@pop}}\fi
 \toks@={\egroup \let\xy@style@=\relax \def\Drop@@}%
 \expandafter\tmp@\expandafter{\Drop@@}%
 \expandafter\addtotoks@\expandafter{\expandafter{\next@}\def\Connect@@}%
 \expandafter\tmp@\expandafter{\Connect@@}%
 \expandafter\addtotoks@\expandafter{\expandafter{\next@}}%
 \the\toks@ }%
\xydef@\xycolor@push@@#1{\special{color push #1}}
\xydef@\xycolor@pop{\special{color pop}}
\xylet@\xycolor@push=\xycolor@push@@
\xydef@\newxycolor#1#2{\newxyColor{#1}{}{}{#2}{}}
\xydef@\newxyColor#1#2#3#4{\newxycolor@{#1}{#2}{#3}{#4}{}}
\xydef@\newxycolor@#1#2#3#4#5{%
 \expandafter\let\expandafter\next@\csname shape [#1]\endcsname
 \ifx\next@\relax
 \DN@{#4}\ifx\next@\empty
 \DN@{#2}\ifx\next@\empty
 \DN@{\newxystyle{#1}{\xylocalColor@{}{#3}\xycolor@{#3}}}%
 \else
 \DN@{\newxystyle{#1}{\xylocalColor@{#2}{#3}\xycolor@{#2 #3}}}%
 \fi
 \else\DN@{#2#3}\ifx\next@\empty
 \DN@{\newxystyle{#1}{\xylocalColor@{#4}{}\xycolor@{#4}}}%
 \else
 \DN@{\newxystyle{#1}{\xylocalColor@{#2}{#3}\xycolor@{#4}}}%
 \fi \fi 
 \else \def\tmp@{\relax}\DNii@{#5}%
 \ifx\nextii@\tmp@
 \DN@{#4}\ifx\next@\empty
 \DN@{#2}\ifx\next@\empty
 \DN@{\newxystyle{#1}{\xylocalColor@{}{#3}\xycolor@{#3}}}%
 \else
 \DN@{\newxystyle{#1}{\xylocalColor@{#2}{#3}\xycolor@{#2 #3}}}%
 \fi
 \else
 \DN@{#2#3}\ifx\next@\empty
 \DN@{\newxystyle{#1}{\xylocalColor@{#4}{}\xycolor@{#4}}}%
 \else
 \DN@{\newxystyle{#1}{\xylocalColor@{#2}{#3}\xycolor@{#4}}}%
 \fi \fi 
 \else\DN@{}\fi\fi \next@\relax}
\xydef@\xystandardcolors@{%
 \newxycolor@{black}{0. 0. 0.}{rgb}{}\relax
 \newxycolor@{white}{1. 1. 1.}{rgb}{}\relax
 \newxycolor@{gray}{.5}{gray}{}\relax
 \newxycolor@{grey}{.5}{gray}{}\relax
 \newxycolor@{red}{1. 0. 0.}{rgb}{}\relax
 \newxycolor@{green}{0. 1. 0.}{rgb}{}\relax
 \newxycolor@{blue}{0. 0. 1.}{rgb}{}\relax
 \newxycolor@{cyan}{0. 1. 1.}{rgb}{}\relax
 \newxycolor@{magenta}{1. 0. 1.}{rgb}{}\relax
 \newxycolor@{yellow}{1. 1. 0.}{rgb}{}\relax
 \xyuncatcodes }
\xydef@\UseCrayolaColors{\xyrequire{crayon}\xyuncatcodes}%
\xydef@\xyBEcolorcheck@{\ifx\xycolor@@\xyNoColor@\else
 \xywarning@{PostScript colour support should be OK.}\fi }%
\xywithoption{ps}{%
 \xyinputorelse@{xyps-c}{\xyerror@{Could not load xyps-c}{}}}%
 \xycatcodes
\xyendinput

xycurve.tex
%% xycurve.tex from $Id: xycurve.doc,v 3.2 1995/09/19 18:20:20 ross Exp ross $
%%
%% Xy-pic ``Curves and Splines'' extension.
%% Copyright (c) 1993-1995 Ross Moore <ross@mpce.mq.edu.au>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined \input xy \fi
\xyprovide{curve}{Curve and Spline extension}{\stripRCS$Revision: 3.2 $}%
 {Ross Moore}{ross@mpce.mq.edu.au}%
 {Mathematics Department, Macquarie University, NSW~2109, Australia}
\message{curve,}
\xynew@{count}\crv@cnt@
\xydef@\xynumctrlpts@{\the\crv@cnt@}
\xynew@{toks}\crvpts@
\xydef@\setcurve@{%
 \edef\xysplineparams@{%
 \expandafter\noexpand\csname params@\endcsname}%
 \edef\xysplineedges@{%
 \expandafter\noexpand\csname edges@\endcsname}%
 \edef\xycrvcnt@{%
 \expandafter\noexpand\csname crvcnt@\endcsname}%
 \expandafter\edef\xycrvcnt@{\number\crv@cnt@}%
 \ifcase\crv@cnt@
 \expandafter\xycvxhull@\or
 \expandafter\xyquadbezier@\or
 \expandafter\xycubicbezier@\or
 \expandafter\xybspline@iii\or
 \expandafter\xybspline@iv\else
 \expandafter\xybspline@
 \fi}
\xydef@\curve{\connect\crv}
\xydef@\crv#1#{\hbox \bgroup \crvresetbreaks@ \initshape@ \crv@{#1}}
\xylet@\crvresetbreaks@=\relax
\xywithoption{arrow}{\let\crvresetbreaks@=\resetbreaks}
\xydef@\crv@#1#2{%
 \DN@{#1}\ifx\empty\next@
 \DN@{\def\afterCURVEaction@{}\parsecurve@\xycurve@@}%
 \else\DN@{\parseCURVE@#1\parsecurve@\curveSTYLE@}\fi
 \next@ #2\@endcurve\endcrv@ }
\xydef@\curveSTYLE@{\xycurve@@}%
\xydef@\afterCURVEaction@{}%
\xydef@\@endcurve{}%
\xydef@\endcrv@@{\endcrv@\POS}%
\xywarnifdefined\crv@normaltemplate
\xywarnifdefined\crv@othertemplate
\xywarnifdefined\crv@specialtemplate@@
{\xyuncatcodes \catcode`\@=11 \catcode`\#=6
 \gdef\crv@normaltemplate#1{{}{~**#1\xy@@crvaddstack@}}
 \gdef\crv@othertemplate#1{{}{~*=<2\jot>{}~**#1\xy@@crvaddstack@}}
 \gdef\crv@specialtemplate@@#1{{}{~**\dir{#1}\xy@@crvaddstack@}}
}
\xydef@\crvs#1#{\hbox \bgroup \crvs@{#1}}%
\xydef@\crvs@#1{\DN@{\initshape@ \@crv@{#1}}%
 \ifx\bstartPLACE@\relax \else \ifx\bstartPLACE@\empty\else 
\splinetrace@{bstartPLACE@=\bstartPLACE@, bendPLACE@=\bendPLACE@}%
 \DN@{\let\xy@@crvaddstack@=\xy@@samecurve@
 \let\saveshape@=\savesame@ 
 \let\savectrlptsnum@=\relax
 \let\startxycurve@=\recovercurve@ 
 \crv@cnt@=\xycrvptsnum@\relax
 \@crv@{#1}}%
 \fi\fi \next@ }
\xydef@\xy@@samecurve@{\xyFN@\checkendcurve@}
\xydef@\savesame@{\egroup }
\xydef@\recovercurve@{\crv@cnt@=\xycrvptsnum@ \splinereset@
 \edef\cv@end{\cfromthec@}%
 \edef\cv@start{\cfromthep@}\splinereset@ }
\xydef@\@crv@#1#2{\DN@{#1#2}%
 \ifx\next@\empty \DN@{\crv@{}{\xy@@crvaddstack@}}%
 \else\def\tmp@{-}\ifx\next@\tmp@ \DN@{\crv@{}{\xy@@crvaddstack@}}%
 \else\def\tmp@{=}\ifx\next@\tmp@ 
 \DN@{\expandafter\crv@\crv@normaltemplate{\dir{=}}}%
 \else\def\tmp@{2-}\ifx\next@\tmp@ 
 \DN@{\expandafter\crv@\crv@normaltemplate{\dir{2.}}}%
 \else\def\tmp@{3-}\ifx\next@\tmp@ 
 \DN@{\expandafter\crv@\crv@normaltemplate{\dir{3.}}}%
 \else\def\tmp@{--}\ifx\next@\tmp@
 \DN@{\expandafter\crv@\crv@specialtemplate@{--}}%
 \else\def\tmp@{==}\ifx\next@\tmp@ 
 \DN@{\expandafter\crv@\crv@normaltemplate{\dir2{--}}}%
 \else\def\tmp@{2--}\ifx\next@\tmp@ 
 \DN@{\expandafter\crv@\crv@normaltemplate{\dir2{--}}}%
 \else\def\tmp@{3--}\ifx\next@\tmp@ 
 \DN@{\expandafter\crv@\crv@normaltemplate{\dir3{--}}}%
 \else\def\tmp@{.}\ifx\next@\tmp@
 \DN@{\expandafter\crv@\crv@specialtemplate@{.}}%
 \else\def\tmp@{:}\ifx\next@\tmp@
 \DN@{\expandafter\crv@\crv@normaltemplate{\dir{:}}}%
 \else\def\tmp@{2.}\ifx\next@\tmp@
 \DN@{\expandafter\crv@\crv@normaltemplate{\dir{:}}}%
 \else\def\tmp@{..}\ifx\next@\tmp@
 \DN@{\expandafter\crv@\crv@specialtemplate@{.}}%
 \else
 \DN@{\expandafter\crv@\crv@othertemplate{\dir#1{#2}}}%
 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xylet@\crv@specialtemplate@=\crv@specialtemplate@@
\xydef@\crv@special#1{}
\xydef@\parseCURVE@{\def\curveSTYLE@{\xycurve@@}\def\afterCURVEaction@{}%
 \xyFN@\parseCURVE@@}
\xydef@\parseCURVE@@{%
 \ifx\space@\next\expandafter\DN@\space{\xyFN@\parseCURVE@@}%
 \else\ifx ~\next \DN@ ~{\xy@~{}\xyFN@\setcurveSTYLE@@}%
 \else\ifx\parsecurve@\next\DN@{}%
 \else\ifcat\active\noexpand\next\DN@{\xyactive@Warning}%
 \else\ifcat a\noexpand\next\DN@##1{\xytilde@Warning\setcurveSTYLE@{##1}%
 \xyFN@\parseCURVE@@}%
 \else\DN@{}\fi\fi\fi\fi\fi \next@ }%
\xydef@\xyactive@Warning{\xywarning@{expandable control sequences should 
 not be here, results are unpredictable in diagrams.}}%
\xydef@\xytilde@Warning{Please use ~ to set curve style.}%
\xydef@\setcurveSTYLE@#1{\xyFN@\setcurveSTYLE@@#1}
\xydef@\setcurveSTYLE@@{%
 \ifx\next p\def\curveSTYLE@{\xyc@trlpts@@}%
 \DN@ p{\xyFN@\setafterCURVEaction@}%
 \else\ifx\next P\def\curveSTYLE@{\xyc@trlpts@}%
 \DN@ P{\xyFN@\setafterCURVEaction@}%
 \else\ifx\next l\def\curveSTYLE@{\xyc@vxhull@@}%
 \DN@ l{\xyFN@\setafterCURVEaction@}%
 \else\ifx\next L\def\curveSTYLE@{\xyc@vxhull@}%
 \DN@ L{\xyFN@\setafterCURVEaction@}%
 \else\ifx\next c\def\curveSTYLE@{\xycurve@@}%
 \DN@ c{\xyFN@\setafterCURVEaction@}%
 \else\ifx\next C\def\curveSTYLE@{\xycurve@@}%
 \DN@ C{\xyFN@\setafterCURVEaction@}%
 \else \DN@##1{\xywarning@{unknown curve style ##1}\xyFN@\parseCURVE@@}%
 \fi\fi\fi\fi\fi\fi \next@ }
\xydef@\setafterCURVEaction@{%
 \ifx\next~\DN@~{\xyFN@\setcurveSTYLE@@}%
 \else\ifcat a\noexpand\next\DN@{\setafterCURVEaction@@}%
 \else\DN@{\xyFN@\parseCURVE@@}%
 \fi\fi \next@}
\xydef@\setafterCURVEaction@@{%
 \ifx\next c\DN@ c{%
 \def\afterCURVEaction@{\noexpand\endcurve\noexpand\xy@curve@}%
 \xyFN@\parseCURVE@@ }%
 \else\ifx\next C\DN@ C{%
 \def\afterCURVEaction@{\noexpand\endcurve\noexpand\xy@curve@@}%
 \xyFN@\parseCURVE@@ }%
 \else \DN@##1{\xywarning@{unknown after-curve action ##1}%
 \xyFN@\parseCURVE@@ }%
 \fi\fi \next@ }
\xydef@\parsecurve@{\xyFN@\parsecurve@@}
\xydef@\parsecurve@@{%
 \ifx\space@\next\expandafter\DN@\space{\xyFN@\parsecurve@@}%
 \else\ifx\next\@endcurve\DN@\@endcurve{\checkafterCURVE@}%
 \else\ifcat\active\noexpand\next\DN@{\relax}%
 \else\DN@{\xycurve@@}\fi\fi\fi\next@}%
\xydef@\xycurve@{\begingroup\afterCURVE{\setcurve@\endgroup}\crvobjects@
 \startxycurve@\xycrvmods@}
\xydef@\xycurve@@{\afterCURVE{\setcurve@}\crvobjects@\startxycurve@
 \xycrvmods@}
\xydef@\xy@curve@{\xy@curve@@@{\splinedefaulttol@\crvobjects@}}
\xydef@\xy@curve@@{\xy@curve@@@{\resetcrvobjects@}}
\xydef@\xy@curve@@@#1{\ifx\cv@start\relax
 \DN@{\xywarning@{There is no curve to plot}}.
 \else\DN@{\begingroup\afterCURVE{\setcurve@\endgroup}%
 #1\cv@end}\fi
 \next@ }
\xydef@\crvobjects@{\def\xycrvdrop@{}\def\xycrvconn@{}}
\xydef@\resetcrvobjects@{\crvobjects@}
\xylet@\savecurve=\xycurve@@
\xylet@\samecurve=\xy@curve@
\xydef@\xycrvmods@{\xyFN@\xy@crvmods@}%
\xydef@\xy@crvmods@{%
 \ifx\space@\next\expandafter\DN@\space{\xyFN@\xy@crvmods@}%
 \else\ifx\next ~\DN@ ~{\xyFN@\xy@crvmods@@}%
 \else\DN@{\xy@crvmods@@@@}\fi\fi \next@}%
\xydef@\xy@crvmods@@@@{\xyFN@\checkendcurve@}%
\xydef@\xy@crvmods@@{%
 \ifx\space@\next\expandafter\DN@\space{\xyFN@\xy@crvmods@@}%
 \else\ifx\next *\DN@ *{\xyFN@\xy@@crvmods@}%
 \else\addAT@\ifx\next\addAT@\DN@{\xyFN@\xy@@crvaddstack}%
 \else\DN@{\xywarning@{badly-formed curve option}\xyFN@\xy@crvmods@}%
 \fi\fi\fi \next@}%
\xydef@\xy@@crvmods@{%
 \ifx\space@\next\expandafter\DN@\space{\xyFN@\xy@@crvmods@}%
 \else\ifx\next *\DN@ *{\xyFN@\xy@@crvmods@@}%
 \else\DN@{\xy@crv@mods@@}\fi\fi \next@}%
\xydef@\xy@crv@mods@@#1#{\DN@##1{\xy@crvmods@@@{#1}{##1}}\next@}%
\xydef@\xy@crvmods@@@#1#2{%
 \DN@{#1#2}\ifx\next@\empty \def\xycrvdrop@{ #1{\zerodot}}%
 \else \def\xycrvdrop@{ #1{#2}}\fi
 \xyFN@\xy@crvmods@ }%
\xydef@\xy@@crvmods@@#1#{\DN@##1{\xy@@crvmods@@@{#1}{##1}}\next@}%
\xydef@\xy@@crvmods@@@#1#2{\def\xycrvconn@{ #1{#2}}\xyFN@\xy@crvmods@ }%
\xydef@\checkendcurve@{%
 \ifx\space@\next\expandafter\DN@\space{\xyFN@\checkendcurve@}%
 \else\ifx\next\endcurve\DN@\endcurve{\clearsearchflag@\endxycurve@}%
 \else\ifx\next\@endcurve\DN@\@endcurve{\checkafterCURVE@}%
 \else\ifx\next\xy@@crvaddstack@\DN@{}%
 \else\ifx\next\endxy\DN@{\clearsearchflag@\sloppyendcrv@}%
 \else\addAND@\ifx\next\addAND@\DN@{\clearsearchflag@\searchnextpt@}%
 \else\ifx ~\next\DN@ ~{\xyFN@\checkcrvtilde@}%
 \else\ifx\next\relax\DN@\relax{\clearsearchflag@\searchnextpt@}%
 \else\ifx\next\\\DN@\\{\clearsearchflag@\searchnextpt@}%
 \else\ifx\searchflag@\relax
 \DN@{\setsearchflag@\searchnextpt@}%
 \else\DN@##1{\flagwarn@{##1}}\fi
 \fi\fi\fi\fi\fi\fi\fi\fi\fi \next@ }
\xydef@\searchnextpt@{\afterPOS{\xy@@\addtocrv@ \xyFN@\checkendcurve@}}
\xydef@\checkafterCURVE@{%
 \edef\tmp@{\noexpand\xyFN@\noexpand\checkendcurve@
 \afterCURVEaction@\noexpand\endcurve}\tmp@ }
\xylet@\searchflag@=\relax
\xydef@\setsearchflag@{\let\searchflag@=@}
\xydef@\clearsearchflag@{\let\searchflag@=\relax}
\xydef@\flagwarn@#1{%
 \ifx\next\@endcurve\DN@{\xyFN@\checkendcurve@\endcurve}%
 \else\setsearchflag@\DN@{\xyFN@\checkendcurve@}%
 \xywarning@{skipping invalid token \string#1\space in curve}%
 \fi \next@ }
\xydef@\sloppyendcrv@{%
\xywarning@{Please use \string\endcurve\space to end the curve.}\endxycurve@}
\xydef@\endcrv@{\saveshape@
 \Edge@c={\splineEdge}\Invisible@false\Hidden@false
 \edef\Drop@@{\noexpand\ifInvisible@ \setbox\z@=\copy\voidb@x
 \noexpand\else
 \noexpand\wdz@=\z@
 \noexpand\ht\z@=\z@ \noexpand\dp\z@=\z@
 \noexpand\splineDrop@
 \noexpand\fi }%
 \edef\Connect@@{%
 \noexpand\setbox\z@=\noexpand\box\lastobjectbox@
 \noexpand\wdz@=\z@
 \noexpand\ht\z@=\z@ \noexpand\dp\z@=\z@
 \noexpand\ifInvisible@ \noexpand\else
 \noexpand\boxz@ \noexpand\fi
 \noexpand\ifHidden@\noexpand\else 
 \noexpand\ifx\noexpand\COORD@\noexpand\xymatrixCOORD@ \noexpand\else
 \noexpand\X@min=\the\X@min \noexpand\X@max=\the\X@max 
 \noexpand\Y@min=\the\Y@min \noexpand\Y@max=\the\Y@max
 \noexpand\fi \noexpand\fi
 \savecrvparams@ \noexpand\crvconnect@ }%
 \wdz@=\z@
 \ht\z@=\z@ \dp\z@=\z@ }
\xydef@\initshape@{\savescope@ 
 \ifdim\X@c>\X@p \X@min=\X@p \X@max=\X@c \else \X@max=\X@p \X@min=\X@c \fi
 \ifdim\Y@c>\Y@p \Y@min=\Y@p \Y@max=\Y@c \else \Y@max=\Y@p \Y@min=\Y@c \fi }
\xydef@\saveshape@{\savectrlptsnum@ 
 \R@c=\X@max \advance\R@c-\X@c \L@c=\X@c \advance\L@c-\X@min
 \U@c=\Y@max \advance\U@c-\Y@c \D@c=\Y@c \advance\D@c-\Y@min
 \edef\tmp@{\egroup \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c
 \noexpand\ifdim\noexpand\X@min>\the\X@min\noexpand\X@min=\the\X@min\noexpand\fi
 \noexpand\ifdim\noexpand\Y@min>\the\Y@min\noexpand\Y@min=\the\Y@min\noexpand\fi
 \noexpand\ifdim\noexpand\X@max<\the\X@max\noexpand\X@max=\the\X@max\noexpand\fi
 \noexpand\ifdim\noexpand\Y@max<\the\Y@max\noexpand\Y@max=\the\Y@max\noexpand\fi
 \savecrvparams@ }\tmp@ }
\xydef@\savecrvparams@{\crvpts@={\the\crvpts@}%
 \noexpand\def\noexpand\crvconnect@{\expandafter\noexpand\crvconnect@}}%
\xydef@\splineEdge{\rectangleEdge}
\xydef@\xy@@crvaddstack{%
 \ifx\next ~\xywarning@{there should be a poslist here, \string~@ ignored}%
 \DN@{\xy@crvmods@}%
 \else\DN@{\xy@@crvaddstack@}\fi \next@}
\xydef@\xy@@crvaddstack@{\smapxy@@\addtocrv@ \xyFN@\checkendcurve@}
\xydef@\checkcrvtilde@{%
 \addAT@\ifx\next\addAT@\DN@{\xy@@crvaddstack@}%
 \else\xywarning@{invalid token after ~, ignored}%
 \DN@##1{\xyFN@\checkendcurve@}%
 \fi \next@ }
\xydef@\crvconnect@@{%
 \def\Creset@@{\crvreset@}%
 \def\Cshavep@@{\crvshavep@}%
 \def\Cshavec@@{\crvshavec@}%
 \def\Cslidep@@{\crvslidep@}%
 \def\Cslidec@@{\crvslidec@}%
 \def\Calong@@{\crvalong@}%
}
\xydef@\straitconnect@{\crvconnect@@ 
 \let\Creset@@=\straitreset@
 \let\Cshavep@@=\straitshavep@
 \let\Cshavec@@=\straitshavec@
 \let\Cslidep@@=\straitslidep@
 \let\Cslidec@@=\straitslidec@
 \let\Calong@@=\straitalong@
}
\xydef@\straitreset@{\the\crvpts@ 
 \edef\xycrvptsnum@{\csname ptsnum@\endcsname}%
 \def\segmentnum@{0}}
\xydef@\straitslidep@{\setupDirection@ii \noCslidep@@ }
\xydef@\straitslidec@{\setupDirection@ii \noCslidec@@ }
\xydef@\straitshavep@{%
 \expandafter\ifnum\xycrvptsnum@>\z@
 \def\segmentnum@{0}%
 \csname cv@1\endcsname 
 \resetDirection@ \setupDirection@ii 
 \fi \noCshavep@@ }
\xydef@\straitshavec@{%
 \expandafter\ifnum\xycrvptsnum@>\z@
 \expandafter\count@@\xycrvptsnum@\relax 
 \bgroup \csname cv@\number\count@@\endcsname 
 \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@ 
 \edef\segmentnum@{\xycrvptsnum@}%
 \resetDirection@ \setupDirection@ii 
 \fi \noCshavec@@ }
\xydef@\straitalong@#1{%
 \ifdim#1\p@<\z@ 
 \xywarning@{parameter value #1 is negative, using 0}%
 \cfromp@ \def\PLACEf@{{0}}%
 \else 
 \dimen@=#1\p@ \count@=\dimen@ \divide\count@\p@ 
 \expandafter\count@@\xycrvptsnum@\relax \advance\count@@\@ne
 \advance\dimen@\segmentnum@\p@ 
 \advance\count@\segmentnum@\relax 
 \def\segmentnum@{0}%
 \ifnum\count@@<\count@
 \xywarning@{parameter value #1 too large, using \the\count@@}%
 \count@=\count@@ \advance\count@\m@ne \edef\PLACEf@{{1}}%
 \else
 \advance\dimen@-\count@\p@ 
 \ifdim\zz@\dimen@\ifnum\count@>\z@
 \advance\count@\m@ne \advance\dimen@\p@ \fi\fi
 \edef\PLACEf@{{\expandafter\removePT@\the\dimen@}}%
 \fi
 \ifnum\count@=\z@\else \bgroup
 \csname cv@\number\count@\endcsname 
 \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@
 \fi
 \advance\count@\@ne
 \ifnum\count@<\count@@
\splinetrace@{find place \the\dimen@\space along straight segment 
 \the\count@}%
 \csname cv@\number\count@\endcsname
 \fi
 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p 
 \fi \expandafter\noCalong@@\PLACEf@ \czeroEdge@ }
\xydef@\splineconnect@{%
 \let\crvreset@=\splinereset@
 \let\crvshavep@=\splineshavep@
 \let\crvshavec@=\splineshavec@
 \let\crvslidep@=\splineslidep@
 \let\crvslidec@=\splineslidec@
 \let\crvalong@=\splinealong@
}
\xydef@\splinereset@{\the\crvpts@ 
 \edef\xycrvptsnum@{\csname ptsnum@\endcsname}%
 \edef\xysplineparams@{%
 \expandafter\noexpand\csname params@\endcsname}%
 \edef\xysplineedges@{%
 \expandafter\noexpand\csname edges@\endcsname}%
 \def\segmentnum@{0}\def\splinecorrect@p{0}\def\splinecorrect@c{0}%
 \splinelength@=\z@ \def\splineplace@f{.5}%
}
\xydef@\splineshavep@{\begingroup 
 \edef\xysplineedges@{%
 \expandafter\noexpand\csname edges@\endcsname}%
 \expandafter\expandafter\expandafter\getsplineedges@safe\xysplineedges@ @@%
 \edef\tmp@{\noexpand\removePT@\the\dimen5}%
 \edef\tmp@{\endgroup 
 \noexpand\def\noexpand\splinecorrect@p{\tmp@}}\tmp@ 
 \setupDirection@ii }
\xydef@\splineshavec@{\begingroup 
 \edef\xysplineedges@{%
 \expandafter\noexpand\csname edges@\endcsname}%
 \expandafter\expandafter\expandafter\getsplineedges@safe\xysplineedges@ @@%
 \dimen@=-\dimen7\relax 
 \expandafter\count@\xycrvptsnum@\relax
 \ifnum\count@>\@ne \advance\count@\m@ne \fi
 \advance\dimen@\count@\p@
 \edef\tmp@{\noexpand\removePT@\the\dimen@}%
 \edef\tmp@{\endgroup 
 \noexpand\def\noexpand\splinecorrect@c{\tmp@}}\tmp@ 
 \setupDirection@ii }
\xydef@\splineslidep@#1{\enter@{\pfromthep@}%
 \begingroup \splinealong@@{0}{#1}+\splineslidep@@@
 \setupDirection@ii \leave@ }%
\xydef@\splineslidep@@@{%
 \d@X=\dimen5 \d@Y=\dimen7 \edef\tmp@{\postfind@}\tmp@ \dimen@=\splineval@
 \expandafter\count@\xycrvptsnum@\relax
 \ifnum\count@>\tw@ \advance\count@\m@ne 
 \advance\dimen@\segmentnum@\p@ \advance\dimen@-\p@ 
 \fi 
 \edef\tmp@{\endgroup \endgroup
 \noexpand\def\noexpand\xysplineval@{\the\splineval@}%
 \noexpand\def\noexpand\splinecorrect@p{\expandafter\removePT@\the\dimen@}%
\splinetrace@{slide = \the\splinelength@}%
 \X@c=\dimen@i \Y@c=\dimen3
 \d@X=\the\d@X \d@Y=\the\d@Y
 \noexpand\def\noexpand\segmentnum@{\segmentnum@}}\tmp@ }
\xydef@\splineslidec@#1{\enter@{\pfromthep@}%
 \begingroup
 \expandafter\splinealong@@\PLACEf@{#1}+\splineslidec@@@
 \setupDirection@ii \leave@ }
\xydef@\splineslidec@@@{%
 \d@X=\dimen5 \d@Y=\dimen7 \edef\tmp@{\postfind@}\tmp@ \dimen@=\splineval@
 \expandafter\count@\xycrvptsnum@\relax
 \ifnum\count@>\tw@ \advance\count@\m@ne 
 \advance\dimen@\segmentnum@\p@ \advance\dimen@-\p@ 
 \dimen@=-\dimen@ \advance\dimen@\count@\p@
 \else \dimen@=-\dimen@ \advance\dimen@\p@ \fi
 \edef\tmp@{\endgroup \endgroup
 \noexpand\def\noexpand\xysplineval@{\the\splineval@}%
 \noexpand\def\noexpand\splinecorrect@c{\expandafter\removePT@\the\dimen@}%
\splinetrace@{slide = \the\splinelength@}%
 \X@c=\dimen@i \Y@c=\dimen3
 \d@X=\the\d@X \d@Y=\the\d@Y
 \noexpand\def\noexpand\segmentnum@{\segmentnum@}}\tmp@ }
\xydef@\checkslidemore@#1{%
 \dimen@ii=-#1\relax\ifdim\dimen@ii<\z@\multiply\dimen@ii\m@ne\fi
 \dimen@=-\splinelength@ \advance\dimen@\dimen@ii\relax 
 \ifdim\dimen@<\z@\dimen@ii=-\dimen@\else\dimen@ii=\dimen@\fi
 \ifdim\dimen@ii<.2\p@\DN@{\splineslidec@@ \leave@}%
 \else \splinetrace@{not found yet, \the\dimen@ii\space still to go}%
 \dimen@ii=#1\relax\ifdim\dimen@ii<\z@\multiply\dimen@\m@ne\fi
 \DN@{\expandafter\splineslidemore@\expandafter{\the\dimen@}}\fi 
 \next@}%
\xydef@\splineslidemore@#1{%
 \expandafter\count@\segmentnum@\relax
 \ifdim#1<\z@\advance\count@\m@ne\dimen@=\p@
 \else\advance\count@\@ne\dimen@=\z@\fi
 \ifnum\count@<\@ne
 \expandafter\splinesegment@\expandafter{\segmentnum@}%
 \DN@{\xywarning@{cannot slide beyond start of curve}%
 \spline@find{\z@}{\z@}{}\splineslidec@@ \leave@ }%
 \else \expandafter\count@@\xycrvptsnum@\relax\advance\count@@\m@ne
 \expandafter\ifnum\count@@<\count@\relax
 \expandafter\splinesegment@\expandafter{\segmentnum@}%
 \DN@{\xywarning@{cannot slide beyond end of curve}%
 \spline@find{\p@}{\z@}{}\splineslidec@@ \leave@ }%
 \else
 \edef\segmentnum@{\the\count@}%
 \expandafter\splinesegment@\expandafter{\segmentnum@}%
\splinetrace@{sliding onto segment \segmentnum@}%
 \expandafter\spline@find\expandafter{\the\dimen@}{#1}{}%
 \DN@{\checkslidemore@{#1}}%
 \fi\fi \next@ }
\xydef@\splineslidec@@{%
 \dimen@=\splineval@ \advance\dimen@\segmentnum@\p@\advance\dimen@-\p@ 
 \edef\tmp@{\endgroup 
 \noexpand\def\noexpand\xysplineval@{\the\dimen@}%
\splinetrace@{slide = \the\splinelength@}%
 \X@c=\the\dimen@i \Y@c=\the\dimen3 \d@X=\the\dimen5 \d@Y=\the\dimen7 \postfind@ 
 \noexpand\def\noexpand\segmentnum@{\segmentnum@}}\tmp@
 \setupDirection@ii}
\xydef@\splinealong@#1{\def\postfind@{}\splinealong@@{#1}\z@+%
 \splineslidec@@}%
\xydef@\splinealong@@#1#2#3{%
 \edef\tmp@{#1}\relax \dimen@ii\tmp@\p@ 
 \expandafter\count@\xycrvptsnum@\relax
 \ifnum\count@>\@ne \advance\count@\m@ne \fi
 \dimen@=-\count@\p@ 
 \expandafter\advance\expandafter\dimen@\splinecorrect@p\p@
 \expandafter\advance\expandafter\dimen@\splinecorrect@c\p@
 \edef\tmp@{#1}\relax \dimen@=-\tmp@\dimen@ \relax
 \expandafter\advance\expandafter\dimen@\splinecorrect@p\p@
\splinetrace@{actual:\the\dimen@; f:\the\dimen@ii; p:\splinecorrect@p, c:\splinecorrect@c}%
 \count@=\dimen@ \divide\count@\p@ \DN@{\relax}%
 \def\tmp@{\relax}\ifx\next@\tmp@
 \expandafter\ifnum\xycrvptsnum@<\count@
 \xywarning@{parameter value #1 too large}\DN@{\relax}%
 \else
 \edef\xysplineval@{\the\dimen@}%
 \advance\dimen@-\count@\p@ 
 \ifdim\dimen@=\z@ 
\splinetrace@{find knot point \the\count@}%
 \ifnum\count@=\z@ \count@=\@ne \else \dimen@=\p@ \fi
 \else \advance\count@\@ne
\splinetrace@{find point \the\dimen@\space on spline segment \the\count@}%
 \fi 
 \edef\segmentnum@{\the\count@}%
 \edef\next@{\begingroup\noexpand\splinesegment@{\the\count@}}%
 \edef\nextii@{%
 \noexpand\spline@find{\the\dimen@}{#2}{}\noexpand\checksplinefind@{#2}}%
 \ifx>#3\relax 
 \edef\nextii@{%
 \noexpand\spline@find{\the\dimen@}{#2}#3\noexpand\checksplinefind@{#2}}%
 \else\ifx-#3\relax \ifdim\dimen@>\z@\relax \ifdim\dimen@<\p@
 \dimen@=-\dimen@ \advance\dimen@\p@
 \edef\nextii@{\noexpand\splinereverse@ 
 \noexpand\spline@find{\the\dimen@}{#2}{}\noexpand\checksplinefind@{#2}}%
 \fi\fi
 \else\ifx<#3\relax \ifdim\dimen@>\z@\relax \ifdim\dimen@<\p@
 \dimen@=-\dimen@ \advance\dimen@\p@
 \edef\nextii@{\noexpand\splinereverse@ 
 \noexpand\spline@find{\the\dimen@}{#2}#3\noexpand\checksplinefind@{#2}}%
 \fi\fi
 \fi\fi\fi
 \fi\fi \expandafter\next@\nextii@ }
\xydef@\checksplinefind@#1{%
 \dimen@ii=#1\relax \dimen@=\splinelength@
 \ifdim\dimen@ii=\z@\DN@{}%
 \else
 \ifdim\dimen@ii<\z@\advance\dimen@\dimen@ii
 \else\advance\dimen@-\dimen@ii\fi
 \ifdim\dimen@<\z@\multiply\dimen@\m@ne\fi
 \ifdim\dimen@<.2\p@\DN@{}%
 \else
 \count@=\segmentnum@\relax 
 \ifdim\dimen@ii<\z@\advance\dimen@ii\splinelength@
 \ifnum\count@>\@ne\advance\count@\m@ne
 \edef\next@{\noexpand\splinesegment@{\the\count@}%
 \noexpand\spline@find\p@{\the\dimen@ii}{}%
 \noexpand\checksplinefind@{\the\dimen@ii}}%
 \else
 \xywarning@{cannot slide \the\dimen@ii\space before start}%
 \DN@{\splinesegment@\@ne \spline@find\z@\z@{}}\fi
 \else\advance\dimen@ii-\splinelength@
 \count@@=\numcontrolpts 
 \ifnum\count@<\count@@ \advance\count@\@ne
 \edef\next@{\noexpand\splinesegment@{\the\count@}%
 \noexpand\spline@find\z@{\the\dimen@ii}{}%
 \noexpand\checksplinefind@{\the\dimen@ii}}%
 \else
 \xywarning@{cannot slide \the\dimen@ii\space beyond end}%
 \DN@{\splinesegment@{\the\count@@}\spline@find\p@\z@{}}\fi
 \fi
 \fi\fi \next@ }
\xydef@\xyclearcrv@{\cv@end\cv@restore\loop@
 \expandafter\let\csname cv@\number\crv@cnt@\endcsname\relax
 \ifnum\crv@cnt@>0\advance\crv@cnt@\m@ne\repeat@
 \let\cv@start=\relax
 \let\cv@end=\relax \let\cv@restore=\relax
 \POS}
\xylet@\clearcurve=\xyclearcrv@
\xylet@\numcontrolpts=\xynumctrlpts@
\xydef@\xycontrolpt@#1{{%
 \ifnum#1<\z@\aftergroup\cv@restore\aftergroup\cv@start
 \else
 \expandafter\count@\xycrvptsnum@\relax \advance\count@\@ne
 \ifnum#1>\count@ \ifx\cv@end\relax 
 \expandafter\aftergroup\csname cv@\number#1\endcsname
 \else\aftergroup\cv@end\fi
 \else 
 \expandafter\ifx\csname cv@\number#1\endcsname\relax
 \ifnum#1=\z@\aftergroup\cv@start\else\aftergroup\cv@end\fi
 \else\expandafter\aftergroup\csname cv@\number#1\endcsname
 \fi\fi\fi}}%
\xylet@\xycontrolpt=\xycontrolpt@
\xydef@\startxycurve@{\crv@cnt@=\z@
 \edef\cv@start{\cfromthep@}%
 \ifdim\zz@\R@c \ifdim\zz@\L@c \ifdim\zz@\D@c \ifdim\zz@\U@c
 \Edge@c={\zeroEdge}\fi\fi\fi\fi
 \edef\cv@end{\cfromthec@}%
 \edef\cv@restore{\pfromthep@\basefromthebase@}}
\xylet@\cv@start=\relax
\xylet@\cv@end=\relax
\xylet@\cv@restore=\relax
\xydef@\readxycurve@{\startxycurve@\xycrvmods@}
\xylet@\readxycurve=\readxycurve@
\xydef@\addtocrv@{\advance\crv@cnt@\@ne 
 \edef\tmp@{%
 \expandafter\noexpand\csname cv@\number\crv@cnt@\endcsname}%
 \expandafter\edef\tmp@{\cfromthec@}%
 \edef\tmp@{\noexpand\addtocrvpts@{\noexpand\def
 \expandafter\noexpand\tmp@{\X@c=\the\X@c \Y@c=\the\Y@c }}}\tmp@
 \edef\xycrvptsnum@{\the\crv@cnt@}%
}
\xydef@\xycrvdrop@{ {\zerodot}}
\xydef@\xycrvconn@{}
\xydef@\xyc@trlpts@{\def\xycrvdrop@{ \dir{x}}\def\xycrvconn@{}%
 \afterCURVE{\savecrvobjects@\xyctrlpts@}\readxycurve@}
\xydef@\xyc@trlpts@@{%
 \afterCURVE{\savecrvobjects@\def\xycrvdrop@{ \dir{x}}%
 \def\xycrvconn@{}\xyctrlpts@}\readxycurve@}
\xydef@\xyc@vxhull@{\def\xycrvdrop@{ {}}\def\xycrvconn@{ \dir{-}}%
 \afterCURVE{\savecrvobjects@\xycvxhull@}\readxycurve@}
\xydef@\xyc@vxhull@@{%
 \afterCURVE{\savecrvobjects@\def\xycrvdrop@{ {}}%
 \def\xycrvconn@{ \dir{-}}\xycvxhull@}\readxycurve@}
\xylet@\controlpts=\xyc@trlpts@
\xylet@\convexhull=\xyc@vxhull@
\xydef@\savecrvobjects@{\bgroup 
 \expandafter\toks@\expandafter{\xycrvdrop@}%
 \expandafter\toks@ii\expandafter{\xycrvconn@}%
 \edef\tmp@{\egroup\noexpand\def\noexpand\resetcrvobjects@{%
 \noexpand\def\noexpand\xycrvdrop@{\the\toks@}%
 \noexpand\def\noexpand\xycrvconn@{\the\toks@ii}%
 }}\tmp@}
\xydef@\afterCURVE#1{\def\afterCURVE@{#1}}
\xydef@\endxycurve@{\cv@end\savectrlptsnum@
 \expandafter\def\csname params@\endcsname{\the\crvpts@}%
 \cv@restore\afterCURVE@\POS}
\xylet@\endcurve=\endxycurve@
\xydef@\moretobedone#1{\xywarning@{\string#1 is not completed yet}} 
\xydef@\notyetdone#1{\xywarning@{\string#1 is not implemented yet}} 
\let\moretobedone=\eat@ \let\notyetdone=\eat@
\xydef@\xyctrlpts@{\cv@end \cv@restore
 \def\crvconnect@{\straitconnect@}%
 \ifnum\crv@cnt@>\z@ 
 \count@@@=\@ne \DN@{\loop@\xycontrolpt@{\count@@@}\relax
 \expandafter\xycvxhulldrop@\xycrvdrop@
 \ifnum\crv@cnt@>\count@@@\advance\count@@@\@ne\repeat@ 
 \cv@end \cv@restore }%
 \else\DN@{\relax}\fi \next@ }
\xylet@\xyctrlpts=\xyctrlpts@
\xydef@\addtocrvpts@#1{\crvpts@=\expandafter{\the\crvpts@#1}}
\xydef@\savescope@{\crvpts@={}%
 \edef\tmp@{\expandafter\noexpand\csname cv@0\endcsname}%
 \edef\tmp@{\noexpand\addtocrvpts@{\noexpand\def
 \expandafter\noexpand\tmp@{\X@c=\the\X@p \Y@c=\the\Y@p}}}%
 \tmp@ }
\xydef@\savectrlptsnum@{%
 \advance\crv@cnt@\@ne 
 \edef\tmp@{%
 \expandafter\noexpand\csname cv@\number\crv@cnt@\endcsname}%
 \edef\tmp@{\noexpand\addtocrvpts@{\noexpand\def
 \expandafter\noexpand\tmp@{\X@c=\the\X@c \Y@c=\the\Y@c}}}\tmp@
 \advance\crv@cnt@\m@ne 
 \edef\tmp@{\expandafter\noexpand\csname ptsnum@\endcsname}%
 \edef\tmp@{\noexpand\addtocrvpts@{%
 \noexpand\def\expandafter\noexpand\tmp@{\number\crv@cnt@}}}%
 \tmp@ }
\xydef@\xycvxhull@{\cv@end \cv@restore 
 \addtocrvpts@{\def\crvconnect@{\straitconnect@}}%
 \def\crvconnect@{\straitconnect@}%
 \ifnum\crv@cnt@>\z@ 
 \count@@@=\@ne\relax \DN@{\loop@\xycontrolpt@{\count@@@}\relax
 \expandafter\xycvxhulldrop@\xycrvdrop@
 {\expandafter\connect@\xycrvconn@\relax}\pfromc@
 \ifnum\crv@cnt@>\count@@@\relax \advance\count@@@\@ne\repeat@ 
 \cv@end }%
 \else
 \ifx\empty\xycrvconn@ \def\xycrvconn@{\dir{-}}\fi
 \DN@{\relax}\fi \next@ 
 {{\expandafter\connect@\xycrvconn@}}%
 \cv@end \cv@restore }
\xylet@\xycvxhull=\xycvxhull@
\xydef@\xycvxhulldrop@#1#{\drop@{#1}}
\xydef@\savespline@{%
 \edef\endspline@{\endgroup 
 \savesplineparams@ \savesplinerefs@
 \X@min=\the\X@min\relax \X@max=\the\X@max\relax
 \Y@min=\the\Y@min\relax \Y@max=\the\Y@max\relax
 \ifInvisible@\noexpand\Invisible@true
 \else\noexpand\Invisible@false\fi
 }\endspline@ 
 \edef\tmp@{\noexpand\addtocrvpts@{\savesplineparams@}}\tmp@
 \xycontrolpt@\z@ \cv@end }
\xydef@\savesplineparams@{%
 \noexpand\def\expandafter\noexpand\xysplineedges@{\xysplineedges@}}
\xydef@\savesplinerefs@{%
 \noexpand\def\noexpand\xysplineparams@{%
 \expandafter\noexpand\xysplineparams@}%
 \noexpand\def\noexpand\xysplineedges@{%
 \expandafter\noexpand\xysplineedges@}%
}
\xynew@{box}\splinebox@ 
\xynew@{dimen}\splineval@ 
\xynew@{dimen}\splinedepth@ 
\xynew@{dimen}\splinetol@ 
\xynew@{dimen}\splinelength@ 
\xynew@{if}\ifsplinefar@
\xynew@{if}\ifsplineplot@
\xydef@\splinetracing{\let\splinetrace@=\W@}
\xydef@\splineignore@#1{}
\xylet@\splinetrace@=\splineignore@
\xydef@\readsplineparams@{%
 \expandafter\expandafter\expandafter\getsplineparams@\xysplineparams@
 \expandafter\expandafter\expandafter\getsplineedges@safe\xysplineedges@ @@}
\xydef@\getsplineedges@safe#1@@{\DN@{#1}%
 \ifx\next@\empty \DN@{\getsplineedges@.0pt;0.0pt,0.0pt;0.0pt,}%
 \else \DN@{\getsplineedges@safe@#1@@}\fi \next@}
\xydef@\getsplineedges@safe@#1;#2,#3@@{\DN@{#3}%
 \ifx\next@\empty \DN@{\getsplineedges@#1;#2,0.0pt;0.0pt,}%
 \else \DN@{\getsplineedges@#1;#2,#3}\fi \next@}
\xydef@\getsplineedges@#1;#2,#3;#4,{%
 \global\dimen@i=#1\global\dimen5=#2\relax
 \dimen@=#3\multiply\dimen@\m@ne \advance\dimen@\splinelength@
 \global\dimen3=\dimen@
 \dimen@=#4\relax \count@=\dimen@ \divide\count@\p@
 \advance\dimen@-\count@\p@ \multiply\dimen@\m@ne
 \advance\dimen@ \count@\p@ \advance\dimen@\p@
 \global\dimen7=\dimen@ }
\xydef@\splinetolerance@#1{\dimen@=#1\relax
 \ifdim\dimen@>\z@ \splinetol@=\dimen@
 \else\splinetol@=.4\p@\fi}
\xylet@\splinedefaulttol@=\relax
\xydef@\splinetolerance#1{\splinetolerance@{#1}%
 \edef\splinedefaulttol@{\splinetol@=\the\splinetol@}}
\splinetolerance\z@
\xydef@\SloppyCurves{\splinetolerance{.8\p@}}
\xydef@\xylowtolerance@{\splinedefaulttol@
 \ifdim\splinetol@<\p@ \divide\splinetol@\tw@ \fi}
\xywarnifdefined\splinedrop@
\xydef@\setstdsplinedrop@{%
 \setbox\splinebox@=\hbox\bgroup
 \setboxz@h{\expandafter\object\xycrvdrop@{}}%
 \splinedefaulttol@ \dimen@=\wd\z@ \dimen@ii=\ht\z@ \advance\dimen@ii\dp\z@
 \ifdim\dimen@ii>\dimen@ \dimen@=\dimen@ii \fi \dimen@=1.4142\dimen@
 \ifdim\dimen@>\splinetol@ \splinetol@=\dimen@\else\dimen@=\splinetol@\fi
 \dimen@=.5\wd\z@ 
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \kern-\dimen@ \Drop@@ \kern\dimen@
 \edef\tmp@{\egroup \splinetol@=\the\splinetol@
 \ifInvisible@\noexpand\Invisible@true
 \else\noexpand\Invisible@false\fi}\tmp@
 \edef\splinedefaulttol@{\splinetol@=\the\splinetol@}%
 \def\splinedrop@{\copy\splinebox@\splineextra@@}}
\xywarnifdefined\splineconn@
\xydef@\stdsplineconn@{{\setsplinedir@
 \setboxz@h\bgroup\expandafter\object\xycrvconn@{}%
 \edef\tmp@{\egroup\L@c=\the\L@c \R@c=\the\R@c \D@c=\the\D@c \U@c=\the\U@c
 \noexpand\def\noexpand\Drop@@{\Drop@@}}\tmp@
 \setboxz@h{\kern-\L@c \boxz@}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \Drop@@}}
\xydef@\setcrvobjects@{\setstdsplinedrop@ \def\splineconn@{\stdsplineconn@}}
\xylet@\splineextra@@=\relax
\xydef@\splinenear@#1#2#3#4{{\d@X=#1\advance\d@X-#2%
 \ifdim\d@X<\z@ \d@X=-\d@X\fi
 \ifdim\splinetol@<\d@X \aftergroup\splinefar@true
 \else \d@Y=#3\advance\d@Y-#4\ifdim\d@Y<\z@ \d@Y=-\d@Y\fi
 \ifdim\splinetol@<\d@Y\aftergroup\splinefar@true
 \else \xydist@\d@X\d@Y
 \ifdim\splinetol@<\dimen@ \aftergroup\splinefar@true
 \else 
 \ifdim\dimen@<.25\splinetol@\aftergroup\splinetooclose@\fi
 \fi\fi\fi}}
\xydef@\splineadvance@@{\global\advance\splineval@\splinedepth@}
\xydef@\splinetooclose@{\aftergroup\aftergroup\aftergroup\splinetooclose@@}
\xydef@\splinetooclose@@{\def\splineplotpt@{\relax}}
\xydef@\splinepoint{%
 {\splinetest@\ifsplineplot@\aftergroup\splinecontinue\fi}}
\xydef@\splinepoint@@{%
\splinetrace@{P@:(\the\X@c,\the\Y@c)::\the\splineval@;\the\splinedepth@}%
 {\splinetest@\ifsplineplot@\relax\else\aftergroup\splinecontinue\fi}}
\xydef@\splinepoint@{%
 {\splinetest@\ifsplineplot@\aftergroup\splinecontinue\fi}}
\xydef@\splinecontinue@{\global\let\splinepoint=\splinepoint@@
 \global\let\splinecontinue=\splinecontinue@@}
\xydef@\splinecontinue@@{\global\let\splinepoint=\splinepoint@
 \global\let\splinecontinue=\relax}
\xylet@\splinecontinue=\splinecontinue@
\xydef@\splineknotpoint@{{\X@p=\X@c \Y@p=\Y@c \cv@start 
 \the\Edge@c\@ne \ifInside@\else\aftergroup\splineknotpoint@@\fi}}%
\xydef@\splineknotpoint@@{{\X@p=\X@c \Y@p=\Y@c \cv@end 
 \the\Edge@c\@ne \ifInside@\else \aftergroup\splinepoint\fi}}%
\xylet@\firstsplinepoint@=\splineknotpoint@
\xylet@\lastsplinepoint@= \splineknotpoint@
\xydef@\splined@@@{%
\splinetrace@{finding end types}%
 \def\splineStarttest{{\X@p=\X@c \Y@p=\Y@c \cv@start \the\Edge@c\@ne 
 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}%
 \def\splineEndtest{{\X@p=\X@c \Y@p=\Y@c \cv@end \the\Edge@c\@ne 
 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}%
 \DN@{\splinescan@}\ifx\bstartPLACE@\empty\else
 \ifx\bstartPLACE@\relax\else\ifx\bstartPLACE@\unknown@\else
 \DN@{\splinescanbreak@}%
 \DNii@{0}\ifx\bstartPLACE@\nextii@ \DNii@{1}\ifx\bendPLACE@\nextii@
 \DN@{}\fi\fi
 \fi\fi\fi \next@ }%
\xydef@\splinescan@{\bgroup%
 \expandafter\def\xysplineedges@{\z@;\z@,\z@;\z@,}%
 \bgroup \cv@start 
 \expandafter\DNii@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
 \ifx\next@\nextii@ \gdef\splineedges@{\z@;\z@,}%
 \else\aftergroup\splinestartScan@\fi
 \egroup
 \bgroup \cv@end 
 \expandafter\DNii@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
 \ifx\next@\nextii@ 
 \splineval@=\z@ \splineRecordValue@
 \else\aftergroup\splineendScan@\fi
 \egroup \egroup
 \expandafter\testsplineedges@\splineedges@;,@@%
 \expandafter\edef\xysplineedges@{\splineedges@}%
 \global\let\splineedges@=\relax
\splinetrace@{edge params: \xysplineedges@}}%
\xydef@\testsplineedges@#1;#2,#3;#4,#5@@{%
 \DN@{#5}\ifx\next@\empty
 \DNii@{#4}\ifx\nextii@\empty
 \xynoedgespline@{end}\def\splineedges@{#1;#2,\z@;\z@,}\fi
 \DNii@{#2}\ifx\nextii@\empty
 \xynoedgespline@{start}\def\splineedges@{\z@;\z@,\z@;\z@,}\fi
 \fi }
\xydef@\xynoedgespline@#1{\xywarning@{#1 edge of spline not found}}%
\xydef@\splinestartScan@{\bgroup
\splinetrace@{scan for start}%
 \global\let\splineadvance@=\splineadvance@@
 \let\spline@start=\splinefindStart@
 \let\spline@end=\spline@end@@
 \let\splinefinish@=\splinefinish@@
 \let\splinewhich=\relax
 \global\splinelength@=\z@
 \def\splinerec@{\let\splinerec@=\splineSrec@ \splinedecast@}%
 \edef\splineedges@{}%
 \expandafter\let\xysplineedges@\relax
 \bgroup \xylowtolerance@ \splined@@ \egroup }%
\xydef@\splineendScan@{%
 \bgroup
\splinetrace@{scan for end}%
 \global\let\splineadvance@=\splineadvance@@
 \let\spline@start=\splinefindEnd@
 \let\spline@end=\spline@end@@ 
 \let\splinefinish@=\splinefinish@@
 \let\splinewhich=\relax
 \global\splinelength@=\z@ 
 \def\splinerec@{\let\splinerec@=\splineErec@ \splinedecast@}%
 \xylowtolerance@ \splined@@ \egroup
 \egroup}
\xydef@\splinescanbreak@{%
 \gdef\breakedges@{}%
 \DN@{0}\ifx\next@\bstartPLACE@
 \DN@{\bgroup \def\tmp@####1;####2,####3;####4,{%
 \global\splineval@=####2\relax}%
 \expandafter\expandafter\expandafter\tmp@\xysplineedges@
 \def\segmentnum@{\@ne}\splineRecordBreakValue@ \egroup}%
 \else
 \bgroup \cv@start 
 \expandafter\DNii@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
 \ifx\next@\nextii@ \aftergroup\splinezerostart
 \else\aftergroup\splinewidestart\fi
 \egroup 
 \fi \next@ 
 \DN@{1}\ifx\next@\bendPLACE@
 \DN@{\bgroup \def\tmp@####1;####2,####3;####4,{%
 \global\splineval@=####4\relax}%
 \expandafter\expandafter\expandafter\tmp@\xysplineedges@
 \def\segmentnum@{\@ne}\splineRecordBreakValue@ \egroup}%
 \else
 \bgroup \cv@end 
 \expandafter\DNii@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
 \ifx\next@\nextii@ \aftergroup\splinezeroend
 \else\aftergroup\splinewideend\fi
 \egroup 
 \fi \next@ 
 \expandafter\def\expandafter
 \xybreakedges@\expandafter{\breakedges@}%
 \global\let\breakedges@=\relax
\splinetrace@{break params: \xybreakedges@::\bstartPLACE@--\bendPLACE@}%
 \expandafter\let\xysplineedges@\xybreakedges@ }
\xydef@\splinezerostart{\DN@{\bgroup 
 \global\splineval@=\bstartPLACE@\p@ 
 \splineRecordBreakValue@ \egroup }}
\xydef@\splinezeroend{\DN@{\bgroup 
 \global\splineval@=\bendPLACE@\p@ 
 \splineRecordBreakEValue@ \egroup }}
\xydef@\splinewidestart{\DN@{\bgroup 
 \splinetrace@{scan for start}%
 \let\splinefbcontinue@=\breakstartcontinue@
 \let\splinef@pt=\splinef@breakpt
 \let\splinef@end=\break@start
 \edef\tmp@{{\bstartPLACE@}}%
 \expandafter\splinealong@@\tmp@\z@>\endgroup\egroup }}
\xydef@\splinewideend{\DN@{\bgroup 
 \splinetrace@{scan for end}%
 \let\splinefbcontinue@=\breakendcontinue@
 \let\splinef@pt=\splinef@breakpt
 \let\splinef@end=\break@end
 \edef\tmp@{{\bendPLACE@}}%
 \expandafter\splinealong@@\tmp@\z@<\endgroup\egroup }}
\xydef@\splineSrec@{{%
\splinetrace@{v=\the\splineval@ + d=\the\splinedepth@ :
 (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c):Srec }%
 \splineStarttest
 \ifsplineplot@ 
 \ifdim\splinedepth@<.0001\p@ \aftergroup\splinefinish@
 \global\advance\splineval@ .5\splinedepth@
 \else\aftergroup\splinedecast@ \fi
 \else \aftergroup\splineadvance@ \fi}}
\xydef@\splinefindStart@@{\bgroup \bgroup 
 \expandafter\expandafter\expandafter\getsplineparams@\xysplineparams@
 \global\let\splineadvance@=\splineadvance@@
 \global\let\splinepoint=\relax
 \let\splinegoal@=\splineRecordValue@ \global\dimen5=\z@ 
 {\X@c=\X@p \Y@c=\Y@p \splinescanStarttest }%
} 
\xydef@\splinefindStart@{%
 \expandafter\crv@cnt@\xycrvptsnum@\relax
 \ifnum\crv@cnt@>\tw@
 \crv@cnt@=\@ne \splineplot@false \splinesegment@{\crv@cnt@}%
 {\splineStarttest
 \ifsplineplot@\aftergroup\splineplot@true\fi}%
 \ifsplineplot@ \else \searchforStartsegment@ \fi 
 \splinesegment@{\crv@cnt@}%
\splinetrace@{start is in segment \segmentnum@}%
 \else \splinesegment@\@ne \fi
 \splineplot@false \splinefindStart@@
}
\xydef@\searchforStartsegment@{\splineplot@true\loop@ 
 \advance\crv@cnt@\@ne 
 \expandafter\count@\xycrvptsnum@\relax
 \ifnum\count@=\crv@cnt@\expandafter\splineplot@false
 \else 
 \splinesegment@{\crv@cnt@}{\splineStarttest
 \ifsplineplot@\aftergroup\splineplot@false
 \else\aftergroup\splineplot@true\fi }%
 \fi \ifsplineplot@\repeat@ 
}
\xydef@\splinefindEnd@@{\bgroup \bgroup
 \expandafter\expandafter\expandafter\getsplineparams@\xysplineparams@
\splinetrace@{params:\xysplineparams@}%
 \splinereverse@@
\splinetrace@{params:\xysplineparams@}%
 \global\let\splineadvance@=\splineadvance@@
 \global\let\splinepoint=\splinescanEndtest 
 \let\splinegoal@=\splineRecordValue@ \global\dimen5=\z@ 
 {\X@c=\X@p \Y@c=\Y@p \splinescanEndtest }%
}
\xydef@\splinereverse@@{\splinereverse@@@}
\xydef@\splinereverse@@@{%
 \def\postspline@{\d@X=-\d@X \d@Y=-\d@Y}%
 \dimen@ii=\X@c \X@c=\X@p \X@p=\dimen@ii 
 \dimen@ii=\Y@c \Y@c=\Y@p \Y@p=\dimen@ii 
 \global\dimen5=-\dimen5\relax 
 \global\advance\dimen5\splinelength@ }
\xydef@\postspline@{}
\xydef@\splineErec@{{%
 \dimen@=\splineval@ \advance\dimen@\splinedepth@
\splinetrace@{ER (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;;
\the\dimen@,\the\splinedepth@}%
 \splineEndtest
 \ifsplineplot@ 
 \ifdim\splinedepth@<.0001\p@ \aftergroup\splinefinish@
 \else\aftergroup\splinedecast@ \fi
 \else \aftergroup\splineadvance@ \fi}}
\xydef@\splinefindEnd@{%
 \expandafter\crv@cnt@\xycrvptsnum@\relax 
 \ifnum\crv@cnt@>\tw@
 \advance\crv@cnt@\m@ne 
 \splineplot@false \splinesegment@{\crv@cnt@}%
 {\X@c=\X@p \Y@c=\Y@p \splineEndtest
 \ifsplineplot@\aftergroup\splineplot@true\fi }%
 \ifsplineplot@ 
 \else \searchforEndsegment@ \fi 
 \splinesegment@{\crv@cnt@}%
\splinetrace@{end is in segment: \segmentnum@ }%
 \else \splinesegment@\@ne \fi
 \splineplot@false\splinefindEnd@@
}
\xydef@\searchforEndsegment@{\splineplot@true\loop@ 
 \advance\crv@cnt@\m@ne 
 \ifnum\crv@cnt@=\z@\expandafter\splineplot@false
 \else 
 \splinesegment@{\crv@cnt@}{\X@c=\X@p \Y@c=\Y@p \splineEndtest
 \ifsplineplot@\aftergroup\splineplot@false
 \else\aftergroup\splineplot@true\fi}%
 \fi \ifsplineplot@\repeat@ 
}
\xydef@\splinescanStarttest{%
\splinetrace@{SST (\the\X@c,\the\Y@c); \the\splinelength@, \the\splineval@}%
 {\splineplot@false\splineStarttest
 \ifsplineplot@\expandafter\splinefinish@\fi}}
\xydef@\splinescanEndtest{%
\splinetrace@{SET (\the\X@c,\the\Y@c); \the\splinelength@, \the\splineval@}%
 {\splineplot@false\splineEndtest 
 \ifsplineplot@\expandafter\splinefinish@\fi}}
\xydef@\splineBrec@{{%
 \dimen@=\splineval@ \advance\dimen@\splinedepth@
\splinetrace@{BR (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;;
\the\dimen@,\the\splinedepth@}%
 \splineEndtest
 \ifsplineplot@ \aftergroup\splineadvance@ \else
 \ifdim\splinedepth@<.0001\p@ \aftergroup\splinefinish@
 \else\aftergroup\splinedecast@ \fi \fi}}
\xydef@\splineBSrec@{{%
\splinetrace@{SR (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;;
\the\dimen@,\the\splinedepth@:SR}%
 \splineStarttest
 \ifsplineplot@ 
 \ifdim\splinedepth@<.0001\p@ \aftergroup\splinefinish@
 \global\advance\splineval@ .5\splinedepth@
 \else \advance\splineval@\splinedepth@
 \splinetest@ \advance\splineval@-\splinedepth@
 \ifsplineplot@\aftergroup\splineadvance@
 \else\aftergroup\splinedecast@\fi
 \fi
 \else
 \global\advance\splineval@\splinedepth@
 \aftergroup\splinefinish@ \fi }}
\xydef@\splineBErec@{{%
 \dimen@=\splineval@ \advance\dimen@\splinedepth@
\splinetrace@{ER (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;;
 \the\dimen@,\the\splinedepth@:ER}%
 \splineEndtest
 \ifsplineplot@ 
 \ifdim\splinedepth@<.0001\p@ \aftergroup\splinefinish@
 \global\advance\splineval@ .5\splinedepth@
 \else \advance\splineval@\splinedepth@
 \splinetest@ \advance\splineval@-\splinedepth@
 \ifsplineplot@\aftergroup\splineadvance@
 \else\aftergroup\splinedecast@\fi
 \fi
 \else
 \global\advance\splineval@\splinedepth@
 \aftergroup\splinefinish@ \fi }}
\xydef@\splinef@breakpt#1{%
 \ifdim\splineval@>\z@
\splinetrace@{found: val=\the\splineval@;(\the\X@c,\the\Y@c)}%
 \else
\splinetrace@{found: val=\the\splineval@;(\the\X@p,\the\Y@p)}%
 \fi \splinefbcontinue@ }
\xydef@\splinef@pt@@{%
 \ifdim\splineval@>\z@ 
\splinetrace@{found: val=\the\splineval@;c:(\the\X@c,\the\Y@c)}%
 \global\dimen@i=\X@c \global\dimen3=\Y@c 
 \else
\splinetrace@{found: val=\the\splineval@;p:(\the\X@p,\the\Y@p)}%
 \fi
 \setsplinedir@ \global\dimen5=\d@X \global\dimen7=\d@Y 
 \global\splineval@=\splineval@
 \aftergroup\splinefocus@ }
\xydef@\findbreakwarning@#1{%
 \xywarning@{#1 of break not found}\splineRecordBreakValue@\egroup}%
\xydef@\breakstartcontinue@{\bgroup \cv@start
 \expandafter\DNii@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
 \ifx\next@\nextii@ \aftergroup\breakstartfound@
 \else\aftergroup\breakstartcontinue@i\fi \egroup }%
\xydef@\breakstartcontinue@i{%
\splinetrace@{move to start edge, from (\the\X@c,\the\Y@c): val=\the\splineval@ }%
 \global\let\splinetest@=\splineStarttest
 \gdef\splinerec@{\global\let\splinerec@=\splineSrec@ \splinedecast@}%
 \global\let\splinepoint=\relax
 \global\let\spline@end=\checkfoundSbreak@ 
 \global\let\splinegoal@=\splineRecordBreakValue@ 
 \global\let\splinefinish@=\splinefinish@@ }
\xydef@\breakstartfound@{%
\splinetrace@{found start edge, at (\the\X@c,\the\Y@c): val=\the\splineval@ }%
 \global\let\splinetest@=\splineStarttest
 \gdef\splinerec@{\splinegoal@ \global\let\splinerec@=\splinefinish@ }%
 \global\let\splinepoint=\relax
 \global\let\spline@end=\checkfoundSbreak@ 
 \global\let\splinegoal@=\splineRecordBreakValue@ 
 \global\let\splinefinish@=\splinefinish@@
 }
\xydef@\checkfoundSbreak@{%
 \ifnum\xycrvptsnum@<\thr@@\DN@{\findbreakwarning@{start}}%
 \else\DN@{\searchBreakSsegment@}\fi \next@ }%
\xydef@\searchBreakSsegment@{%
 \crv@cnt@=\segmentnum@ \DN@{}\count@=\crv@cnt@
 \DNii@{}\ifnum\splineval@=\z@ \ifnum\crv@cnt@=\@ne
 \ifnum\xycrvptsnum@=\@ne\count@=\z@\DNii@{\egroup}\fi
 \else \DN@{\egroup}\fi 
 \else \ifnum\splineval@=\m@ne 
 \else \advance\crv@cnt@\@ne \fi \fi
 \ifnum\crv@cnt@=\xycrvptsnum@\relax
 \ifnum\xycrvptsnum@>\tw@ \DNii@{\egroup}\fi
 \DN@{\expandafter\splineRecordBreakValue@\nextii@}%
 \else
 \DN@{\splinesegment@{\crv@cnt@}\splinesetparams@
 \splined@@ \egroup}%
 \fi \next@ }
\xydef@\checkfoundEbreak@{%
 \ifnum\xycrvptsnum@<\thr@@\DN@{\findbreakwarning@{end}}%
 \else\DN@{\searchBreakEsegment@}\fi \next@ }%
\xydef@\searchBreakEsegment@{%
 \crv@cnt@=\segmentnum@ \DN@{}\count@=\crv@cnt@
 \DNii@{}\ifnum\splineval@=\z@ \ifnum\crv@cnt@=\@ne
 \ifnum\xycrvptsnum@=\@ne\count@=\z@\DNii@{\egroup}\fi
 \else\DN@{\egroup}\fi
 \else \advance\crv@cnt@\m@ne \fi 
 \ifnum\count@=\z@
 \ifnum\xycrvptsnum@>\tw@ \splineval@=\m@ne\p@
 \DNii@{\egroup}\fi
 \DN@{\expandafter\splineRecordBreakValue@\nextii@}\else
 \DN@{\splinesegment@{\crv@cnt@}\splinereverse@
 \readsplineparams@ \splined@@ \egroup}%
 \fi \next@ }
\xydef@\break@start{\egroup \egroup 
\splinetrace@{scan for start}%
 \global\let\splineadvance@=\splineadvance@@
 \let\spline@start=\splinefindBStart@
 \let\spline@end=\egroup
 \let\splinefinish@=\splinefinish@@
 \let\splinewhich=\relax
 \global\let\splineadvance@=\splineadvance@@
 \global\let\splinepoint=\relax
 \let\splinegoal@=\splineRecordBreakValue@
 \global\dimen5=\z@ \global\splinelength@=\z@
 \let\splinerec@=\splineSrec@ 
 \def\breakedges@{}%
 \bgroup \bgroup \splined@@ }
\xydef@\splinefindBStart@{\bgroup
 \global\splineval@=\z@ \global\splinedepth@=.5\p@}
\xydef@\breakendcontinue@{\bgroup \cv@end
 \expandafter\DNii@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
 \ifx\next@\nextii@ \aftergroup\breakendfound@
 \else\aftergroup\breakendcontinue@i\fi \egroup }%
\xydef@\breakendcontinue@i{%
\splinetrace@{move to end edge, from (\the\X@c,\the\Y@c): val=\the\splineval@ }%
 \global\let\splinetest@=\splineEndtest
 \gdef\splinerec@{\global\let\splinerec@=\splineErec@\splinedecast@}%
 \global\let\splinepoint=\relax
 \global\let\spline@end=\checkfoundEbreak@ 
 \global\let\splinegoal@=\splineRecordBreakValue@ 
 \global\let\splinefinish@=\splinefinish@@ }
\xydef@\breakendfound@{%
\splinetrace@{found end edge, at (\the\X@c,\the\Y@c): val=\the\splineval@ }%
 \global\let\splinetest@=\splineEndtest
 \gdef\splinerec@{\splinegoal@ \global\let\splinerec@=\splinefinish@}%
 \global\let\splinepoint=\relax
 \global\let\spline@end=\checkfoundEbreak@ 
 \global\let\splinegoal@=\splineRecordBreakValue@ 
 \global\let\splinefinish@=\splinefinish@@ }
\xydef@\break@end{\egroup \egroup
 \global\let\splineadvance@=\splineadvance@@
 \let\spline@start=\splinefindBEnd@
 \let\spline@end=\egroup 
 \let\splinefinish@=\splinefinish@@
 \let\splinewhich=\relax
 \global\let\splineadvance@=\splineadvance@@
 \global\let\splinegoal@=\splineRecordBreakValue@
 \global\splinelength@=\z@ 
 \let\splinerec@=\splineErec@ 
 \bgroup \splined@@ }
\xydef@\splinefindBEnd@{\bgroup\bgroup 
 \splinereverse@ \readsplineparams@ 
 \global\splineval@=\z@ }
\xydef@\splineRecordValue@{%
 \ifx\unknown\segmentnum@\relax
 \else\expandafter\advance\expandafter\splineval@\segmentnum@\p@
 \advance\splineval@-\p@ \fi
 \xdef\splineedges@{\splineedges@\the\splinelength@;\the\splineval@,}%
\splinetrace@{found edge: \splineedges@}}
\xydef@\splineRecordBreakValue@{%
 \ifx\unknown\segmentnum@\relax
 \else\expandafter\advance\expandafter\splineval@\segmentnum@\p@
 \advance\splineval@-\p@ \fi
 \xdef\breakedges@{\breakedges@\the\splinelength@;\the\splineval@,}%
 \global\let\spline@end=\egroup
\splinetrace@{found break edge: \breakedges@}}
\xydef@\splineRecordBreakEValue{%
 \ifdim\splineval@>\z@
 \splineval@=-\splineval@ \advance\splineval@\p@ \fi
 \splineRecordBreakValue@ }%
\xydef@\xydist@#1#2{\ifdim#1>#2\relax
 \quotient@@\tmp@#2#1\expandafter\dimen@ii\tmp@#2\relax
 \ifdim\dimen@ii>.41422#1\relax
 \dimen@=1.060665#1\advance\dimen@ .353555\dimen@ii\relax
 \else \dimen@=#1\advance\dimen@.5\dimen@ii\fi
 \else 
 \quotient@@\tmp@#1#2\expandafter\dimen@ii\tmp@#1\relax
 \ifdim\dimen@ii>.41422#2\relax
 \dimen@=1.060665#2\advance\dimen@ .353555\dimen@ii\relax
 \else \dimen@=#2\advance\dimen@.5\dimen@ii\fi
 \fi}
\xydef@\splineDadvance@{\splineadvance@@
 \expandafter\splineDadvance@@\splineDadvance@@@}
\xydef@\splineDadvance@@#1#2#3#4{%
 {\d@X=#1\advance\d@X-#2\ifdim\d@X<\z@ \d@X=-\d@X\fi 
 \d@Y=#3\advance\d@Y-#4\ifdim\d@Y<\z@ \d@Y=-\d@Y\fi
 \xydist@\d@X\d@Y
 \global\advance\splinelength@\dimen@ 
}}
\xydef@\spline@end@{\lastsplinepoint@ \egroup \egroup
 \ht\z@=\z@ \dp\z@=\z@ \wdz@=\z@ \boxz@}%
\gdef\splinetest@{\splineplot@true}
\xydef@\spline@end@@{\egroup\egroup}
\xydef@\splinefrec@{{%
 \advance\splineval@\splinedepth@
\splinetrace@{F:(\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;
\the\splineval@;\the\splinedepth@}%
 \ifdim\dimen5=\splineval@ \aftergroup\splinefinishf@ 
 \else \dimen@=\dimen5\advance\dimen@-\splineval@
 \ifdim\dimen@<\z@ \dimen@=-\dimen@ \fi
 \ifdim\dimen@<.0001\p@ \aftergroup\splinefinishf@
 \else
 \ifdim\dimen5<\splineval@\aftergroup\splinedecast@
 \else \aftergroup\splineadvance@ 
 \fi\fi\fi}}
\xydef@\splinefinishf@{\global\advance\splineval@\splinedepth@
 \splinefinish@}%
\xydef@\spline@find#1#2#3{%
 \readsplineparams@
 \global\let\splinefinish@=\splinefinish@@
 \global\let\splinegoal@=\splinef@pt 
 \global\let\splinepoint=\relax
 \dimen@=#1\relax\dimen@ii=#2\relax
 \ifdim\dimen@ii=\z@ \def\postfind@{}%
 \else\def\postfind@{}%
 \ifdim\dimen@ii<\z@ \splinereverse@ 
 \readsplineparams@ 
\splinetrace@{reverse orientation: (\the\X@p,\the\Y@p),(\the\X@c,\the\Y@c)}%
 \dimen@=#1\relax\dimen@ii=#2\relax
 \multiply\dimen@\m@ne \advance\dimen@\p@ \multiply\dimen@ii\m@ne
 \def\postfind@{\d@X=-\the\d@X \d@Y=-\the\d@Y \noexpand\reversesplineval@}%
 \fi\fi
 \expandafter\splinetrace@\expandafter{\xysplineparams@}%
 \edef\next@{\noexpand\spline@@find{\the\dimen@}{\the\dimen@ii}{#3}}%
 \next@ }
\xydef@\reversesplineval@{\splineval@=-\splineval@ \advance\splineval@\p@ }
\xydef@\spline@@find#1#2#3{%
 \let\splinerec@=\splinefrec@ 
 \global\let\splineadvance@=\splineadvance@@
 \dimen5=#1\relax
 \ifdim #2=\z@\relax
 \ifdim #1=\z@\relax \bgroup 
 \let\splined@@=\spline@@knot
 \global\splineval@=\m@ne\p@ 
 \else\ifdim #1=\p@\relax \bgroup
 \let\splined@@=\spline@@knot 
 \global\splineval@=\z@ 
 \else 
 \global\let\splineadvance@=\splineadvance@@
 \DN@{#3}\ifx\next@\empty \setsplinetest@\splineval@>{#1}{}%
 {{\ifdim\splineval@=\dimen5\aftergroup\splineplot@false\fi}}%
 \else\DNii@{>}\ifx\next@\nextii@
 \setsplineundertest@\splineval@>{#1}{}{}%
 \let\splinerec@=\splineBSrec@ 
 \else\DNii@{<}\ifx\next@\nextii@
 \setsplineundertest@\splineval@>{#1}{}{}%
 \let\splinerec@=\splineBErec@ 
 \else\xywarning@{unknown find-mode: #3}\fi\fi\fi
 \fi\fi
 \else 
 \def\splineslidetest@@{%
 \setsplinetest@\splinelength@<{#2}{}{}}%
 \let\splinefinish@=\splinefcontinue@
 \fi
 \let\spline@end=\splinef@end
 \let\splinepoint@=\relax
 \splinelength@=\z@ 
 \def\spline@start{\bgroup\xylowtolerance@}%
 \splined@@ }
\xydef@\spline@@knot{%
 \let\setsplinedir@=\setsplineknotdir@
 \splinesetparams@\spline@start
 \global\splinedepth@=\p@
 \global\dimen@i=\X@p \global\dimen3=\Y@p 
 \splinefinishf@ \spline@end \egroup }
\xydef@\splinefcontinue@{%
\splinetrace@{sliding... from (\the\X@c,\the\Y@c): val=\the\splineval@ }%
 \global\let\splinerec@=\splinerec@@
 \global\splinelength@=\z@
 \global\splineval@=\splineval@
 \global\let\splinepoint=\splinefindtest@
 \global\let\splinegoal@=\splinef@pt 
 \global\let\splineadvance@=\splineDadvance@
 \global\let\splinefinish@=\splinefinish@@ 
 \splineslidetest@@ 
 }
\xydef@\splinefindtest@{%
\splinetrace@{SFT (\the\X@c,\the\Y@c); \the\splinelength@, \the\splineval@}%
 {\splineplot@false\splinetest@ 
 \ifsplineplot@\expandafter\splinefinishf@\fi}}
\def\setsplineundertest@#1#2#3#4#5{%
 \DNii@{\gdef\splinetest@}%
 \DN@##1\next{\def\tmp@{{\splineplot@false 
 \ifdim#1#2##1\relax #4\else\splineplot@true#5\fi }}}%
 \next@#3\relax\next
 \expandafter\nextii@\tmp@ }
\xydef@\splinef@end{\edef\tmp@{\egroup\splinelength@=\the\splinelength@}\tmp@}
\xydef@\splinef@pt{%
 \ifdim\splineval@>\z@ 
\splinetrace@{found: val=\the\splineval@;c:(\the\X@c,\the\Y@c)}%
 \global\dimen@i=\X@c \global\dimen3=\Y@c 
 \else
\splinetrace@{found: val=\the\splineval@;p:(\the\X@p,\the\Y@p)}%
 \fi
 \setsplinedir@ \global\dimen5=\d@X \global\dimen7=\d@Y 
 \global\splineval@=\splineval@
 \aftergroup\splinefocus@ }
\def\setsplinetest@#1#2#3#4#5{%
 \DNii@{\gdef\splinetest@}%
 \DN@##1\next{\def\tmp@{{\splineplot@false \ifdim#1#2##1\relax
 #4\else\splineplot@true#5\fi}}}%
 \next@#3\relax\next
 \expandafter\nextii@\tmp@ }%
\xydef@\splinefocus@{%
 \d@X=\dimen5\relax \d@Y=\dimen7\relax \setsplinedir@ }
\xydef@\splinesegment@#1{}
\xydef@\xyprecurve@{}
\xydef@\xypostcurve@{}
\xydef@\splineset@{%
 \ifx\bstartPLACE@\empty\splinetrace@{invisible curve}%
 \DN@{\xyprecurve@ 
 \edef\tmp@{\egroup \X@max=\the\X@max \X@min=\the\X@min
 \Y@max=\the\Y@max \Y@min=\the\Y@min}\tmp@ \xypostcurve@ }%
 \else
 \DN@{\xyprecurve@ \xysplinespecialcases@
 \edef\tmp@{\egroup \X@max=\the\X@max \X@min=\the\X@min
 \Y@max=\the\Y@max \Y@min=\the\Y@min}\tmp@ \xypostcurve@ }%
 \fi
 \next@ }
\xydef@\xysplinespecialcases@{%
 \ifx\empty\xycrvdrop@ 
 \ifx\empty\xycrvconn@ \DN@{\splinesolid@}%
 \else \DN@{ \dir{-}}\ifx\next@\xycrvconn@ \DN@{\splinesolid@}%
 \else \DN@{ \dir 2{-}}\ifx\next@\xycrvconn@ \DN@{\splinedoubled@}%
 \else \DN@{ \dir{=}}\ifx\next@\xycrvconn@ \DN@{\splineribboned@}%
 \else \DN@{ \dir {2.}}\ifx\next@\xycrvconn@ \DN@{\splinedoubled@}%
 \else \DN@{ \dir 3{-}}\ifx\next@\xycrvconn@ \DN@{\splinetrebled@}%
 \else \DN@{ \dir {3.}}\ifx\next@\xycrvconn@ \DN@{\splinetrebled@}%
 \else \DN@{ \dir{--}}\ifx\next@\xycrvconn@ \DN@{\splinedashed@}%
 \else \DN@{ \dir{.}}\ifx\next@\xycrvconn@ \DN@{\splinedotted@}%
 \else \DN@{ \dir{:}}\ifx\next@\xycrvconn@ \DN@{\splinedbldotted@}%
 \else \ifdim\splinetol@>\z@ \else \splinedefaulttol@ \fi
 \DN@{\splineset@@}\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
 \else
 \DN@{\splineset@@}%
 \fi \next@}
\xydef@\splinesolid@{\setbox\splinebox@=\zerodot \def\xycrvdrop@{ }%
 \def\xycrvconn@{}\splineset@@}
\xydef@\splinedoubled@{\splinedefaulttol@\def\xycrvdrop@{ }\def\splinedrop@{}%
 \def\xycrvconn@{\dir2{.}}\splineset@@}
\xydef@\splineribboned@{\splinedefaulttol@\def\xycrvdrop@{ }\def\splinedrop@{}%
 \def\xycrvconn@{\dir{:}}\splineset@@}
\xydef@\splinetrebled@{\splinedefaulttol@\def\xycrvdrop@{ }\def\splinedrop@{}%
 \def\xycrvconn@{\dir3{.}}\splineset@@}
\xydef@\splinedashed@{\splinetol@=1pc \def\xycrvdrop@{ }\def\splinedrop@{}%
 \def\xycrvconn@{\dir{-}}\splineset@@}
\xydef@\splinedotted@{\setbox\splinebox@=\zerodot \def\xycrvdrop@{ }%
 \splinetol@=\jot \def\xycrvconn@{}\splineset@@}
\xydef@\splinedbldotted@{\def\xycrvdrop@{ }\def\splinedrop@{}%
 \splinetol@=\jot \def\xycrvconn@{\dir{:}}\splineset@@}
\xydef@\splineset@@{%
 \readsplineparams@
 \ifx\xycrvdrop@\empty \splinetol@=7.5\p@
 \def\splinedefaulttol@{\splinetol@=7.5\p@}\def\splinedrop@{}%
 \else\edef\splinedefaulttol@{\splinetol@=\the\splinetol@}\fi
 \ifx\xycrvconn@\empty \def\splineconn@{}\fi
\splinetrace@{set the curve}%
 \global\let\splineadvance@=\splineadvance@@
 \let\splinerec@=\splineTrec@
 \def\splineStarttest{\splinetest@}%
 \let\splinepoint=\relax
 \let\spline@start=\spline@start@
 \let\spline@end=\spline@end@
 \ifdim\dimen7=\p@ 
 \gdef\splinecontinue{\splinesetting@
 \global\let\splinetest@=\splineplot@true}%
 \else \ifdim\dimen7=\tw@\p@ \emptyspline@
 \gdef\splinecontinue{\splinesetting@
 \global\let\splinetest@=\splineplot@false
 \global\dimen5=\z@ }%
 \else\xdef\splinecontinue{\noexpand\setsplinetest@
 \splineval@>{\the\dimen7}{\noexpand\splinebreakcancel@}{}%
 \noexpand\splinesetting@ }\fi\fi
 \ifdim\zz@{\dimen5}\DN@{\splinesetting@\splinecontinue}%
 \else\edef\next@{\noexpand\setsplinetest@
 \splineval@<{\the\dimen5}{}%
 {\noexpand\expandafter\noexpand\splinecontinue}%
 \noexpand\splinesetting@ }\fi \next@
 \ifdim\dimen5=\p@\DN@{}\else\DN@{\splined@@}\fi \next@ }
\xydef@\emptyspline@{\xywarning@{empty curve subsegment}}
\xydef@\splineTrec@{{%
 \advance\splineval@\splinedepth@
 \ifdim\dimen5=\splineval@
 \aftergroup\splinecontinue
 \else \dimen@=\dimen5\advance\dimen@-\splineval@
 \ifdim\dimen@<\z@ \dimen@=-\dimen@ \fi
 \ifdim\dimen@<.001\p@
 \aftergroup\splinecontinue
 \else
 \ifdim\dimen5<\splineval@\aftergroup\splinedecast@
 \else \aftergroup\splineadvance@
 \fi\fi\fi}}
\xydef@\splinesetting@{\xyFN@\splinesetting@@}
\xydef@\splinesetting@@{%
 \ifdim\splinedepth@=\p@
 \def\splinerec@{\global\let\splinerec@=\splinerec@@\splinedecast@}%
 \else \global\let\splinerec@=\splinerec@@ \fi
 \gdef\splinepoint{\splineplotpt@}}
\xydef@\splineplotpt@{{\global\advance\dimen@i-\X@c 
 \splinetest@ \ifsplineplot@ 
 \ifdim\dimen@i<\z@
 \raise\Y@c\hbox to-\dimen@i{\hfill\splinedrop@}%
 \else \kern-\dimen@i\raise\Y@c\hbox{\splinedrop@}\fi
 \ifx\splineconn@\relax\else\raise\Y@c\hbox{%
 \setboxz@h{\splineconn@}\Drop@@}\fi
\splinetrace@{P:(\the\X@c,\the\Y@c);;\the\dimen@i;\the\dimen3%
 ,\the\splinelength@,\the\splineval@,\the\splinedepth@}%
 \else 
\splinetrace@{N:(\the\X@c,\the\Y@c);;\the\dimen@i;\the\dimen3%
 ,\the\splinelength@,\the\splineval@,\the\splinedepth@}%
 \hglue-\dimen@i 
 \fi 
 \global\dimen@i=\X@c \global\dimen3=\Y@c 
}}
\xydef@\splinefinish@@{\postspline@ \splinegoal@ \splinecancel@ }
\xydef@\splinecancel@{%
 \global\let\splinerec@=\relax
 \global\let\splinepoint=\relax 
 \global\let\splinecontinue=\relax
 }
\xydef@\splinebreakcancel@{\bsplinecancel@ \splinecancel@}
\xydef@\bsplinecancel@{\gdef\lastbspline@{\leave@\leave@}%
 \global\let\middlebspline@=\lastbspline@ }
\xydef@\splinegoal@{\ifdim\splineval@>\z@
 \global\dimen@i=\X@c \global\dimen3=\Y@c \fi
 \global\splineval@=\splineval@ \global\splinelength@=\splinelength@
 \setsplineTangent@ }
\xylet@\splinefinish@\splinefinish@@
\xylet@\splinewhich\splineDwhich@
\xydef@\squinewhich@{%
 \ifdim\dimen5>\squinelength
 \d@X=\X@c \d@Y=\Y@c \advance\d@X-\L@c \advance\d@Y-\U@c 
 \advance\squineval-\squinedepth 
 \else \X@c=\X@p \Y@c=\Y@p \advance\squineval-\squinedepth
 \d@X=\L@c \d@Y=\U@c \advance\d@X-\X@p \advance\d@Y-\Y@p \fi
 \d@X=-\d@X \d@Y=-\d@Y
 \squinefinish}
\xydef@\squineDwhich@{%
 \ifdim\dimen5>\squinelength
 \d@X=\X@c \d@Y=\Y@c \advance\d@X-\L@c \advance\d@Y-\U@c 
 \else \X@c=\X@p \Y@c=\Y@p \advance\squineval-\squinedepth
 \d@X=\L@c \d@Y=\U@c \advance\d@X-\X@p \advance\d@Y-\Y@p \fi
 \d@X=-\d@X \d@Y=-\d@Y
 \squinefinish}
\xydef@\xyquadbezier@{%
 \global\let\splinerec@=\relax
 \addtocrvpts@{\def\crvconnect@{\squineconnect@}}%
 \xyquadmethods@ \let\splinesegment@=\squinesegment@
 \begingroup\setcrvobjects@ \xysplineparams@ \splined@@@
 \bgroup \setupsquine@ \squined@ \splineset@ \savespline@ }
\xydef@\xyquadmethods@{%
 \def\crvconnect@{\squineconnect@}%
 \def\splinereverse@@{\splinereverse@@@}%
 \let\getsplineparams@=\getsquineparams@
 \let\spline@start@=\squine@start@
 \let\splinedecast@=\squinedecast@
 \let\splinerec@@=\squinerec@
 \let\splined@@=\squined@@
 \let\splineinfo@=\squineinfo@
 \let\setsplinedir@=\setsquinedir@
 \let\setsplineknotdir@=\setsquineknotdir@
 \let\splinereverse@=\squinereverse@
 \let\splineDadvance@@@=\squineDadvance@@@
 \let\splinesetparams@=\squinesetparams@
}
\xydef@\squineconnect@{\splineconnect@ \crvconnect@@ 
 \let\splinesegment@=\squinesegment@ }%
\xydef@\squinesegment@#1{\xyquadmethods@ \def\segmentnum@{\@ne}%
 \setupsquine@ \squined@ }
\xydef@\setupsquine@{%
 \xycontrolpt@\z@ \X@p=\X@c \Y@p=\Y@c
 \xycontrolpt@\@ne \A@=\X@c \B@=\Y@c 
 \xycontrolpt@\tw@ 
 \ifdim \A@>\X@max
 \dimen@=\X@p\advance\dimen@\A@ \divide\dimen@\tw@
 \ifdim \dimen@>\X@max \X@max=\dimen@ \fi
 \dimen@=\X@c\advance\dimen@\A@ \divide\dimen@\tw@
 \ifdim \dimen@>\X@max \X@max=\dimen@ \fi
 \else \ifdim \A@<\X@min 
 \dimen@=\X@p\advance\dimen@\A@ \divide\dimen@\tw@
 \ifdim \dimen@<\X@min \X@min=\dimen@ \fi
 \dimen@=\X@c\advance\dimen@\A@ \divide\dimen@\tw@
 \ifdim \dimen@>\X@min \X@min=\dimen@ \fi
 \fi\fi
 \ifdim \B@>\Y@max 
 \dimen@=\Y@p\advance\dimen@\B@ \divide\dimen@\tw@
 \ifdim \dimen@>\Y@max \Y@max=\dimen@ \fi
 \dimen@=\Y@c\advance\dimen@\B@ \divide\dimen@\tw@
 \ifdim \dimen@>\Y@max \Y@max=\dimen@ \fi
 \else \ifdim \B@<\Y@min
 \dimen@=\Y@p\advance\dimen@\B@ \divide\dimen@\tw@
 \ifdim \dimen@<\Y@min \Y@min=\dimen@ \fi
 \dimen@=\Y@c\advance\dimen@\B@ \divide\dimen@\tw@
 \ifdim \dimen@>\Y@min \Y@min=\dimen@ \fi
 \fi\fi }
\xydef@\squinedecast@{\divide\splinedepth@\tw@ 
 \R@c=\L@c \advance\L@c\X@p \divide\L@c\tw@
 \advance\R@c\X@c \divide\R@c\tw@
 \A@=\L@c \advance\A@\R@c \divide\A@\tw@
 \D@c=\U@c \advance\U@c\Y@p \divide\U@c\tw@
 \advance\D@c\Y@c \divide\D@c\tw@
 \B@=\U@c \advance\B@\D@c \divide\B@\tw@
 \begingroup \X@c=\A@ \Y@c=\B@ \splinerec@ \endgroup
 \begingroup \X@c=\A@ \Y@c=\B@ \splinepoint \endgroup
 \X@p=\A@ \L@c=\R@c \Y@p=\B@ \U@c=\D@c \splinerec@}
\xydef@\squinerec@{{\splinefar@false \splinenear@\X@p\X@c\Y@p\Y@c 
 \ifsplinefar@ \aftergroup\squinedecast@ 
 \else \aftergroup\splineadvance@ \fi}}
\xydef@\squineDadvance@@@{\X@p\L@c\Y@p\D@c}
\xydef@\setsquinedir@{%
 \d@X=\X@c \advance\d@X-\L@c \d@Y=\Y@c \advance\d@Y-\U@c 
 \dimen@=\ifdim\d@X<\z@-\fi\d@X \ifdim\dimen@<.02\p@
 \dimen@=\ifdim\d@Y<\z@-\fi\d@Y \ifdim\dimen@<.02\p@ 
 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p \fi\fi
 \ifdim\X@c=\X@p \ifdim\Y@c=\Y@p 
 \d@X=\L@c \advance\d@X-\X@p \d@Y=\U@c \advance\d@Y-\Y@p \fi\fi
 \setupDirection@ii } 
\xydef@\setsquineknotdir@{%
 \ifdim\zz@\splineval@ \expandafter \setsquinezerodir@
 \else\expandafter \setsquinedir@ \fi } 
\xydef@\setsquinezerodir@{%
 \d@X=\L@c \advance\d@X-\X@p \d@Y=\U@c \advance\d@Y-\Y@p 
 \ifdim\zz@\d@X \ifdim\zz@\d@Y 
 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p 
 \fi\fi \setupDirection@ii }
\xydef@\getsquineparams@#1,#2,#3,#4,#5,#6,#7,{%
 \splinelength@=#1\relax\X@p=#2\relax\Y@p=#3\relax
 \A@=#4\relax\B@=#5\relax\X@c=#6\relax\Y@c=#7\relax
}
\xydef@\squineinfo@{%
\expandafter\removePT@\the\X@c\space
\expandafter\removePT@\the\Y@c\space
\expandafter\removePT@\the\A@\space
\expandafter\removePT@\the\B@\space
\expandafter\removePT@\the\X@p\space
\expandafter\removePT@\the\Y@p\space
\expandafter\removePT@\the\dimen5\space\space
\expandafter\removePT@\the\dimen7\space
 }%
\xydef@\squinereverse@{\readsplineparams@
 \expandafter\edef\xysplineparams@{\the\splinelength@,%
 \the\X@c,\the\Y@c,\the\A@,\the\B@,\the\X@p,\the\Y@p,}}%
\xydef@\squine@start@{\setboxz@h\bgroup
 \global\splinelength@=\z@ \global\dimen@i=\z@ \global\dimen3=\z@
 \kern\X@p
 {\squinesetparams@ \X@c=\X@p \Y@c=\Y@p \firstsplinepoint@
 }\bgroup }
\xydef@\squinesetparams@{%
 \global\dimen@i=\X@p \global\dimen3=\Y@p 
 \L@c=\A@ \U@c=\B@ \R@c=\L@c \D@c=\U@c }%
\xydef@\squined@{%
 \expandafter\edef\xysplineparams@{%
 \the\z@,\the\X@p,\the\Y@p,\the\A@,\the\B@,\the\X@c,\the\Y@c,}}
\xydef@\squined@@{%
 \global\splinedepth@=\p@ 
 \global\splineval@=\z@ 
 \global\dimen@i=\X@p \global\dimen3=\Y@p
 \spline@start
 \ifx\splinerec@\relax \let\splinerec@=\squinerec@\fi
 \L@c=\A@ \U@c=\B@ \R@c=\L@c \D@c=\U@c 
 \splinerec@ \spline@end }
\xydef@\xycubicbezier@{%
 \addtocrvpts@{\def\crvconnect@{\cubicconnect@}}%
 \xycubicmethods@ \let\splinesegment@=\cubicsegment@
 \begingroup \setcrvobjects@ \xysplineparams@ \splined@@@ 
 \bgroup \setupcubic@ \cubiced@ \splineset@ \savespline@ }
\xydef@\xycubicmethods@{%
 \def\crvconnect@{\cubicconnect@}%
 \def\splinereverse@@{\cubicreverse@@}%
 \let\getsplineparams@=\getcubicparams@
 \let\spline@start@=\cubic@start@
 \let\splinedecast@=\cubicdecast@
 \let\splinerec@@=\cubicrec@
 \let\splined@@=\cubiced@@
 \let\splineinfo@=\cubicinfo@
 \let\setsplinedir@=\setcubicdir@
 \let\setsplineknotdir@=\setcubicknotdir@
 \let\splinereverse@=\cubicreverse@ 
 \let\splineDadvance@@@=\cubicDadvance@@@
 \let\splinesetparams@=\cubicsetparams@
 }
\xydef@\cubicconnect@{\splineconnect@ \crvconnect@@
 \let\splinesegment@=\cubicsegment@ }%
\xydef@\cubicsegment@#1{\xycubicmethods@ \def\segmentnum@{\@ne}%
 \setupcubic@ \cubiced@ }
\xydef@\setupcubic@{%
 \xycontrolpt@\z@ \X@p=\X@c \Y@p=\Y@c
 \xycontrolpt@\@ne \A@=\X@c \B@=\Y@c 
 \xycontrolpt@\tw@ \global\dimen3=\X@c \global\dimen5=\Y@c
 \xycontrolpt@\thr@@ 
 \adjustmaxmin@ }
\xydef@\adjustmaxmin@{%
 \ifdim \A@>\X@max \dimen@=\A@ \advance\dimen@\X@p \divide\dimen@\tw@ 
 \ifdim\dimen@>\X@max \X@max=\dimen@ \fi \else
 \ifdim \A@<\X@min \dimen@=\A@ \advance\dimen@\X@p \divide\dimen@\tw@ 
 \ifdim\dimen@<\X@min \X@min=\dimen@ \fi \fi\fi
 \ifdim \B@>\Y@max \dimen@=\B@ \advance\dimen@\Y@p \divide\dimen@\tw@ 
 \ifdim\dimen@>\Y@max \Y@max=\dimen@ \fi \else
 \ifdim \B@<\Y@min \dimen@=\B@ \advance\dimen@\Y@p \divide\dimen@\tw@ 
 \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi \fi\fi
 \ifdim \dimen3>\X@max \dimen@=\dimen3\advance\dimen@\X@c \divide\dimen@\tw@ 
 \ifdim\dimen@>\X@max \X@max=\dimen@ \fi \else
 \ifdim \dimen3<\X@min \dimen@=\dimen3\advance\dimen@\X@c \divide\dimen@\tw@ 
 \ifdim\dimen@<\X@min \X@min=\dimen@ \fi \fi\fi
 \ifdim \dimen5>\Y@max \dimen@=\dimen5\advance\dimen@\Y@c \divide\dimen@\tw@ 
 \ifdim\dimen@>\Y@max \Y@max=\dimen@ \fi \else
 \ifdim \dimen5<\Y@min \dimen@=\dimen5\advance\dimen@\Y@c \divide\dimen@\tw@ 
 \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi \fi\fi
 \dimen@=\A@ \advance\dimen@\dimen3\divide\dimen@\tw@
 \ifdim\dimen@>\X@max \X@max=\dimen@
 \else \ifdim\dimen@<\X@min \X@min=\dimen@ \fi\fi
 \dimen@=\B@ \advance\dimen@\dimen5\divide\dimen@\tw@
 \ifdim\dimen@>\Y@max \Y@max=\dimen@
 \else \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi\fi
}
\xydef@\cubicdecast@{\divide\splinedepth@\tw@
\A@=\L@c \advance\A@\R@c \divide\A@\tw@
\advance\R@c\X@c \divide\R@c\tw@
\B@=\U@c \advance\B@\D@c \divide\B@\tw@
\advance\D@c\Y@c \divide\D@c\tw@
\advance\L@c\X@p \divide\L@c\tw@
\advance\U@c\Y@p \divide\U@c\tw@
\begingroup 
\X@c=\R@c \advance\X@c\L@c \divide\X@c\tw@ 
 \advance\X@c\A@ \divide\X@c\tw@
\Y@c=\D@c \advance\Y@c\U@c \divide\Y@c\tw@ 
 \advance\Y@c\B@ \divide\Y@c\tw@
\R@c=\L@c \advance\R@c\A@ \divide\R@c\tw@
\D@c=\U@c \advance\D@c\B@ \divide\D@c\tw@
\bgroup \splinerec@ \egroup 
\splinepoint \endgroup
\X@p=\L@c \advance\X@p\R@c \divide\X@p\tw@
 \advance\X@p\A@ \divide\X@p\tw@
\L@c=\R@c \advance\L@c\A@ \divide\L@c\tw@
\Y@p=\U@c \advance\Y@p\D@c \divide\Y@p\tw@
 \advance\Y@p\B@ \divide\Y@p\tw@
\U@c=\D@c \advance\U@c\B@ \divide\U@c\tw@
\splinerec@ }
\xydef@\cubicrec@{{\splinefar@false \splinenear@\X@p\X@c\Y@p\Y@c 
 \ifsplinefar@ \aftergroup\cubicdecast@
 \else \aftergroup\splineadvance@ \fi}}
\xydef@\cubicDadvance@@@{\X@p\X@c\Y@p\Y@c}
\xydef@\cubiced@@{%
 \global\splinedepth@=\p@ 
 \global\splineval@=\z@ 
 \spline@start 
 \global\dimen@i=\X@p \global\dimen3=\Y@p
 \splinerec@ \spline@end }
\xydef@\setcubicdir@{%
 \ifdim\splinedepth@<.001\p@\DN@{\cubiccoarsedir@}%
 \else\DN@{\cubicfinedir@}\fi \next@ }
\xydef@\cubicfinedir@{%
 \d@X=\X@c \advance\d@X-\R@c \d@Y=\Y@c \advance\d@Y-\D@c 
 \ifdim\zz@\d@X \ifdim\zz@\d@Y 
 \d@X=\X@c \advance\d@X-\L@c \d@Y=\Y@c \advance\d@Y-\U@c 
 \ifdim\zz@\d@X \ifdim\zz@\d@Y 
 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p 
 \fi\fi \fi\fi
 \setupDirection@ii 
\splinetrace@{dir:(\the\d@X,\the\d@Y),\the\Direction; depth:\the\splinedepth@}} 
\xydef@\cubiccoarsedir@{%
 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p \setupDirection@ii
 \global\dimen5=\d@X \global\dimen7=\d@Y
\splinetrace@{dir:(\the\d@X,\the\d@Y),\the\Direction; depth:\the\splinedepth@}} 
\xydef@\setcubicknotdir@{%
 \ifdim\zz@\splineval@ \DN@{\setcubiczerodir@}%
 \else \DN@{\cubicfinedir@}\fi \next@ } 
\xydef@\setcubiczerodir@{%
 \d@X=\L@c \advance\d@X-\X@p \d@Y=\U@c \advance\d@Y-\Y@p 
 \ifdim\zz@\d@X \ifdim\zz@\d@Y 
 \d@X=\R@c \advance\d@X-\X@p \d@Y=\D@c \advance\d@Y-\Y@p 
 \ifdim\zz@\d@X \ifdim\zz@\d@Y 
 \d@X=\X@c \advance\d@X-\X@p \d@Y=\Y@c \advance\d@Y-\Y@p 
 \fi\fi \fi\fi \setupDirection@ii }
\xydef@\getcubicparams@#1,#2,#3,#4,#5,#6,#7,#8,#9,{%
 \splinelength@=#1\relax\X@p=#2\relax\Y@p=#3\relax\L@c=#4\relax
 \U@c=#5\relax\R@c=#6\relax\D@c=#7\relax\X@c=#8\relax\Y@c=#9\relax
}%
\xydef@\cubicinfo@{%
\expandafter\removePT@\the\X@p\space
\expandafter\removePT@\the\Y@p\space
\expandafter\removePT@\the\L@c\space
\expandafter\removePT@\the\U@c\space
\expandafter\removePT@\the\R@c\space
\expandafter\removePT@\the\D@c\space
\expandafter\removePT@\the\X@c\space
\expandafter\removePT@\the\Y@c\space
\expandafter\removePT@\the\dimen5\space\space
\expandafter\removePT@\the\dimen7\space
 }%
\xydef@\cubicreverse@{\readsplineparams@
 \expandafter\edef\xysplineparams@{\the\splinelength@,%
 \the\X@c,\the\Y@c,\the\R@c,\the\D@c,\the\L@c,\the\U@c,\the\X@p,\the\Y@p,}}%
\xydef@\cubicreverse@@{%
 \splinereverse@@@ 
 \dimen@ii=\L@c \L@c=\R@c \R@c=\dimen@ii 
 \dimen@ii=\U@c \U@c=\D@c \D@c=\dimen@ii }
\xydef@\cubic@start@{\setboxz@h\bgroup
 \global\splinelength@=\z@ \global\dimen@i=\z@ \global\dimen3=\z@
 \kern\X@p
 {\cubicsetparams@ \X@c=\X@p \Y@c=\Y@p \R@c=\X@c \D@c=\Y@c
 \firstsplinepoint@ }\bgroup 
}
\xydef@\cubicsetparams@{%
 \expandafter\expandafter\expandafter\getsplineparams@\xysplineparams@
 \global\dimen@i=\X@p \global\dimen3=\Y@p }
\xydef@\cubiced@{%
 \expandafter\edef\xysplineparams@{\the\z@,\the\X@p,\the\Y@p
 ,\the\A@,\the\B@,\the\dimen3,\the\dimen5,\the\X@c,\the\Y@c,}%
 }%
\xydef@\xybspline@iii{%
 \addtocrvpts@{\def\crvconnect@{\bsplineiiiconnect@}}%
 \def\crvconnect@{\bsplineiiiconnect@}\xybsplinemethods@ 
 \let\splinesegment@=\bsplinesegment@iii
 \begingroup\setcrvobjects@ \dobspline@ \savespline@ }
\xydef@\bsplineiiiconnect@{\splineconnect@ \crvconnect@@
 \let\splinesegment@=\bsplinesegment@iii }%
\xydef@\xybspline@iv{%
 \addtocrvpts@{\def\crvconnect@{\bsplineivconnect@}}%
 \def\crvconnect@{\bsplineivconnect@}\xybsplinemethods@
 \let\splinesegment@=\bsplinesegment@iv
 \begingroup\setcrvobjects@ \dobspline@ \savespline@ }
\xydef@\bsplineivconnect@{\splineconnect@ \crvconnect@@
 \let\splinesegment@=\bsplinesegment@iv }%
\xydef@\xybspline@{%
\splinetrace@{B-spline with \numcontrolpts\space control points.}%
 \addtocrvpts@{\def\crvconnect@{\bsplineconnect@}}%
 \def\crvconnect@{\bsplineconnect@}\xybsplinemethods@ 
 \let\splinesegment@=\bsplinesegment@ 
 \begingroup\setcrvobjects@
 \dobspline@ \savespline@ }
\xydef@\xybsplinemethods@{%
 \def\splinereverse@@{\cubicreverse@@}%
 \let\getsplineparams@=\getbsplineparams@
 \let\spline@start@=\cubic@start@
 \let\splinedecast@=\cubicdecast@
 \let\splinerec@@=\cubicrec@
 \let\splined@@=\bsplined@@
 \let\splineinfo@=\cubicinfo@
 \let\setsplinedir@=\setcubicdir@
 \let\setsplineknotdir@=\setcubicknotdir@
 \let\splinereverse@=\cubicreverse@ 
 \let\splineDadvance@@@=\cubicDadvance@@@
 \let\splinesetparams@=\cubicsetparams@
 \global\let\lastbspline@=\lastbspline@@
 \global\let\middlebspline@=\middlebspline@@
}
\xydef@\bsplined@@{%
 \global\splinedepth@=\p@ 
 \global\splineval@=\z@ 
 \spline@start 
 \global\dimen@i=\X@p \global\dimen3=\Y@p
 \splinerec@ \spline@end }
\xydef@\bsplineconnect@{\splineconnect@ \crvconnect@@
 \let\splinesegment@=\bsplinesegment@ }%
\xydef@\getbsplineparams@{\getcubicparams@}
\xydef@\dobspline@{\xysplineparams@ \scanbspline@ \firstbspline@ }%
\xydef@\firstbspline@{%
 \enter@{\pfromthep@ \cfromthec@}\enter@{\cfromthec@}\bgroup
 \def\segmentnum@{1}\xycontrolpt@\z@ \X@p=\X@c \Y@p=\Y@c
\splinetrace@{0: \the\X@p, \the\Y@p}%
 \xycontrolpt@\@ne \A@=\X@c \B@=\Y@c 
\splinetrace@{1: \the\X@c, \the\Y@c}%
 \xycontrolpt@\tw@ 
\splinetrace@{2: \the\X@c, \the\Y@c}%
 \dimen@=\X@c \advance\dimen@\A@ \divide\dimen@\tw@
 \global\dimen3=\dimen@
 \dimen@=\Y@c \advance\dimen@\B@ \divide\dimen@\tw@
 \global\dimen5=\dimen@
 \xycontrolpt@{3}%
\splinetrace@{3: \the\X@c, \the\Y@c}%
 \expandafter\count@\xycrvcnt@\relax
 \ifnum\count@=3\relax 
 \advance\X@c-\A@ \divide\X@c by4\advance\X@c\dimen3\relax
 \advance\Y@c-\B@ \divide\Y@c by4\advance\Y@c\dimen5\relax
 \enter@{\X@p=\the\X@c \Y@p=\the\Y@c \crv@cnt@=\@ne\relax
 \noexpand\lastbspline@ }%
 \else 
 \advance\X@c 7\dimen3\advance\X@c-2\A@ \divide\X@c by6\relax
 \advance\Y@c 7\dimen5\advance\Y@c-2\B@ \divide\Y@c by6\relax
 \enter@{\X@p=\the\X@c \Y@p=\the\Y@c \crv@cnt@=\@ne\relax
 \noexpand\middlebspline@ }%
 \fi \adjustmaxmin@ \czeroEdge@
 \bsplined@ \splineset@ \leave@ }
\xydef@\lastbspline@@{\bgroup 
 \advance\crv@cnt@\@ne \edef\segmentnum@{\the\crv@cnt@}%
\splinetrace@{<: \the\X@p, \the\Y@p}%
 \advance\crv@cnt@\@ne \xycontrolpt@{\crv@cnt@}%
 \global\dimen3=\X@c \global\dimen5=\Y@c
\splinetrace@{\the\crv@cnt@: \the\X@c, \the\Y@c}%
 \advance\crv@cnt@\m@ne \xycontrolpt@{\crv@cnt@}%
\splinetrace@{\the\crv@cnt@: \the\X@c, \the\Y@c}%
 \A@=\X@c \advance\A@\dimen3\divide\A@\tw@
 \B@=\Y@c \advance\B@\dimen5\divide\B@\tw@
 \adjustmaxmin@ \leave@
\splinetrace@{>: \the\X@c, \the\Y@c}%
 \bsplined@ \splineset@ \leave@ }%
\xylet@\lastbspline@=\lastbspline@@
\xydef@\middlebspline@@{%
 \advance\crv@cnt@\@ne \edef\segmentnum@{\the\crv@cnt@}%
\splinetrace@{<: \the\X@p, \the\Y@p}%
 \bgroup 
 \xycontrolpt@{\crv@cnt@}\A@=2\X@c \B@=2\Y@c
\splinetrace@{\the\crv@cnt@: \the\X@c, \the\Y@c}%
 \advance\crv@cnt@\@ne \xycontrolpt@{\crv@cnt@}%
\splinetrace@{\the\crv@cnt@: \the\X@c \the\Y@c}%
 \advance\A@\X@c \divide\A@ by3\advance\B@\Y@c \divide\B@ by3\relax
 \advance\X@c\A@ \divide\X@c\tw@ \advance\Y@c\B@ \divide\Y@c\tw@
 \global\dimen3=\X@c \global\dimen5=\Y@c 
 \advance\crv@cnt@\@ne \xycontrolpt@{\crv@cnt@}%
\splinetrace@{\the\crv@cnt@: \the\X@c \the\Y@c}%
 \expandafter\count@\xycrvcnt@\relax 
 \ifnum\crv@cnt@<\count@\relax 
 \advance\X@c 7\dimen3\advance\X@c-2\A@ \divide\X@c by6\relax
 \advance\Y@c 7\dimen5\advance\Y@c-2\B@ \divide\Y@c by6\relax
 \enter@{\X@p=\the\X@c \Y@p=\the\Y@c \crv@cnt@=\segmentnum@\relax
 \noexpand\middlebspline@}%
 \else 
 \advance\X@c-\A@ \divide\X@c by4\advance\X@c \dimen3\relax
 \advance\Y@c-\B@ \divide\Y@c by4\advance\Y@c \dimen5\relax
 \enter@{\X@p=\the\X@c \Y@p=\the\Y@c \noexpand\lastbspline@}%
 \fi \adjustmaxmin@ 
 \bsplined@ \splineset@ \leave@ } 
\xylet@\middlebspline@=\middlebspline@@
\xydef@\scanbspline@{\splined@@@}
\xydef@\bsplined@{\cubiced@ 
 \expandafter\ifx\xysplineedges@\relax\relax\DN@{}%
 \else\DN@{\adjustbsplineedges@}\fi \next@ }
\xydef@\adjustbsplineedges@{\bgroup
 \readsplineparams@ 
 \count@@=\dimen7\divide\count@@\p@ 
 \advance\dimen7-\count@@\p@ \advance\count@@\@ne 
 \count@=\dimen5\divide\count@\p@ 
 \advance\dimen5-\count@\p@ \advance\count@\@ne
\splinetrace@{segment \segmentnum@:\the\count@,\the\count@@:\xysplineedges@}%
\splinetrace@{params:\xysplineparams@}%
 \expandafter\ifnum\segmentnum@=\count@
 \else
 \expandafter\ifnum\segmentnum@<\count@\dimen5=\p@
 \else\dimen5=\z@ \fi\fi
 \expandafter\ifnum\segmentnum@=\count@@
 \multiply\dimen7by\m@ne \advance\dimen7by\p@
 \else
 \expandafter\ifnum\segmentnum@>\count@@\dimen5=\p@\dimen7=\p@
 \else\dimen7=\z@ \fi\fi
 \expandafter\edef\xysplineedges@{%
 \noexpand\z@;\the\dimen5,\noexpand\z@;\the\dimen7,}%
 \edef\tmp@{\egroup 
 \noexpand\def\expandafter\noexpand\xysplineedges@{\xysplineedges@}}%
 \tmp@ }
\xydef@\bsegment@@ii@iii{%
 \xycontrolpt@{\count@@}\global\dimen3=\X@c \global\dimen5=\Y@c
\splinetrace@{\the\count@@: \the\X@c \the\Y@c}%
 \advance\count@@\@ne \xycontrolpt@{\count@@}\A@=\X@c \B@=\Y@c
 \advance\A@ by2\dimen3\divide\A@ by3\relax
 \advance\B@ by2\dimen5\divide\B@ by3\relax
 \dimen@=\dimen3 \advance\dimen@ by2\X@c \divide\dimen@\thr@@
 \global\dimen3=\dimen@
 \dimen@=\dimen5 \advance\dimen@ by2\Y@c \divide\dimen@\thr@@ 
 \global\dimen5=\dimen@
 \advance\count@@\m@ne }
\xydef@\bsegment@@i{\bgroup
 \advance\count@@\m@ne \xycontrolpt@{\count@@}%
\splinetrace@{\the\count@@: \the\X@c \the\Y@c}%
 \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@
 \advance\X@p-2\dimen3\advance\X@p by7\A@ \divide\X@p by6\relax
 \advance\Y@p-2\dimen5\advance\Y@p by7\B@ \divide\Y@p by6\relax 
}
\xydef@\bsegment@@iv{%
 \advance\count@@\tw@ \xycontrolpt@{\count@@}%
\splinetrace@{\the\count@@: \the\X@c \the\Y@c}%
 \advance\X@c by7\dimen3\advance\X@c-2\A@ \divide\X@c by6\relax
 \advance\Y@c by7\dimen5\advance\Y@c-2\B@ \divide\Y@c by6\relax 
}
\xydef@\bsegment@@ii@i{\bgroup
 \advance\count@@\m@ne \xycontrolpt@{\count@@}%
\splinetrace@{\the\count@@: \the\X@c \the\Y@c}%
 \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@
 \advance\X@p-\dimen3\advance\X@p by4\A@ \divide\X@p by4\relax
 \advance\Y@p-\dimen5\advance\Y@p by4\B@ \divide\Y@p by4\relax
}
\xydef@\bsegment@@y@iv{%
 \advance\count@@\tw@ \xycontrolpt@{\count@@}%
\splinetrace@{\the\count@@: \the\X@c \the\Y@c}%
 \advance\X@c by4\dimen3\advance\X@c-\A@ \divide\X@c by4\relax
 \advance\Y@c by4\dimen5\advance\Y@c-\B@ \divide\Y@c by4\relax
}
\xydef@\bsegment@i{%
 \xycontrolpt@\z@ \X@p=\the\X@c \Y@p=\the\Y@c
\splinetrace@{0: \the\X@p \the\Y@p}%
 \xycontrolpt@\@ne
\splinetrace@{1: \the\X@c \the\Y@c}\A@=\X@c \B@=\Y@c 
 \xycontrolpt@\tw@
 \dimen@=\X@c \advance\dimen@\A@ \divide\dimen@\tw@
 \global\dimen3=\dimen@
\splinetrace@{2: \the\X@c \the\Y@c}%
 \dimen@=\Y@c \advance\dimen@\B@ \divide\dimen@\tw@
 \global\dimen5=\dimen@ }
\xydef@\bsegment@i@iv{%
 \xycontrolpt@{3}%
\splinetrace@{3: \the\X@c \the\Y@c}%
 \advance\X@c by7\dimen3\advance\X@c-2\A@ \divide\X@c by6\relax
 \advance\Y@c by7\dimen5\advance\Y@c-2\B@ \divide\Y@c by6\relax
 }
\xydef@\bsegment@z{%
 \expandafter\count@@\xycrvptsnum@ \advance\count@@\@ne 
 \xycontrolpt@{\the\count@@}\relax\edef\tmp@{\X@c=\the\X@c \Y@c=\the\Y@c}%
\splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
 \advance\count@@\m@ne \xycontrolpt@{\the\count@@}%
\splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
 \global\dimen3=\X@c \global\dimen5=\Y@c
 \advance\count@@\m@ne \xycontrolpt@{\the\count@@}%
\splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
 \A@=\X@c \advance\A@\dimen3\divide\A@\tw@
 \B@=\Y@c \advance\B@\dimen5\divide\B@\tw@ \tmp@
 }
\xydef@\bsegment@z@i{%
 \expandafter\count@@\xycrvptsnum@\relax\advance\count@@-\tw@ 
 \edef\tmp@{\X@c=\the\X@c \Y@c=\the\Y@c}%
 \xycontrolpt@{\count@@}\X@p=\the\X@c \Y@p=\the\Y@c
\splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
 \advance\X@p by7\A@ \advance\X@p-2\dimen3\divide\X@p by6\relax
 \advance\Y@p by7\B@ \advance\Y@p-2\dimen5\divide\Y@p by6\relax 
 \tmp@ }
\xydef@\bsplinesegment@#1{\xybsplinemethods@ 
 \count@@=#1\relax 
 \ifnum\count@@=\@ne
 \bsegment@i \bsegment@i@iv
 \else\ifnum\count@@=\tw@
 \bsegment@@ii@iii \bsegment@@ii@i \bsegment@@iv
 \else\expandafter\count@\xycrvptsnum@\advance\count@\m@ne
 \ifnum\count@@=\count@
 \bsegment@z \bsegment@z@i 
 \else\advance\count@\m@ne
 \ifnum\count@@=\count@
 \bsegment@@ii@iii \bsegment@@i \bsegment@@y@iv
 \else
 \bsegment@@ii@iii \bsegment@@i \bsegment@@iv
 \fi\fi\fi\fi 
 \def\segmentnum@{\number#1}\bsplined@ }
\xydef@\bsplinesegment@iii#1{\xybsplinemethods@ 
\splinetrace@{2 segments; \number#1}%
 \count@@=#1\relax 
 \ifnum\count@@=\@ne \bsegment@i 
 \xycontrolpt@{3}%
\splinetrace@{3: \the\X@c, \the\Y@c}%
 \advance\X@c 4\dimen3\advance\X@c-\A@ \divide\X@c by4\relax
 \advance\Y@c 4\dimen5\advance\Y@c-\B@ \divide\Y@c by4\relax
 \else\ifnum\count@@=\tw@ \bsegment@z 
 \bgroup\xycontrolpt@{\@ne}%
\splinetrace@{1: \the\X@c, \the\Y@c}%
 \edef\tmp@{\egroup \X@p=\the\X@c \Y@p=\the\Y@c}\tmp@
 \advance\X@p 4\A@ \advance\X@p-\dimen3\divide\X@p by4\relax
 \advance\Y@p 4\B@ \advance\Y@p-\dimen5\divide\Y@p by4\relax
 \fi\fi \def\segmentnum@{\number#1}\bsplined@
}
\xydef@\bsplinesegment@iv#1{\xybsplinemethods@ 
\splinetrace@{3 segments; \number#1}%
 \count@@=#1\relax 
 \ifnum\count@@=\@ne \bsegment@i \bsegment@i@iv
 \else\ifnum\count@@=\tw@
 \bsegment@@ii@iii \bsegment@@ii@i \bsegment@@y@iv
 \else\ifnum\count@@=3\relax
 \bsegment@z \bsegment@z@i
 \fi\fi\fi \def\segmentnum@{\number#1}\bsplined@
 }
\message{circles,}
\xydef@\Circmagic@@{0.5517847}
\xylet@\Circmagic=\Circmagic@@
\xydef@\twoPi@{6.2831852}
\xydef@\fullPi@{3.1415926}
\xydef@\halfPi@{1.5707963}
\xynew@{dimen}\L@
\xydef@\xycircle#1#{\hbox\bgroup\afterVECTORorEMPTY{%
 \xy@@{\R@=\X@c \L@=\Y@c}\xycircle@}{\xy@@{\R@=\R@c \L@=\L@c}\xycircle@}#1@}
\xydef@\xycircle@#1@#2{%
 \DN@{#1}\ifx\next@\empty\def\onlyQuad@{}\else \count@=#1\relax 
 \ifnum\count@<5 \advance\count@-3\relax 
 \ifnum\count@<\z@ \advance\count@ 4\relax\fi \edef\onlyQuad@{\the\count@}%
 \else\xyerror@{illegal circle <radius>: must be <vector> or <empty>}{}\fi
 \fi \xy@@{\def\circleSTYLE@{#2}}\def\circleSTYLE@{#2}\xycircle@i}
\xydef@\xycircle@i{\hbox{\vbox{\vskip\L@
 \hbox to2\R@{\hfill \buildcircle@ \hfill}\vskip\L@ }}%
 \L@c=\R@ \R@c=\R@ \D@c=\L@ \U@c=\L@ \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\boxz@}\def\Connect@@{\straight@\relax}\Edge@c={\circleEdge}%
 \OBJECT@x}
\xydef@\adjustMinMaxcirc@#1#2{%
 \dimen@=\X@c \advance\dimen@#1\relax\ifdim\dimen@>\X@max \X@max=\dimen@\fi
 \dimen@=\X@c \advance\dimen@-#1\relax\ifdim\dimen@<\X@min \X@min=\dimen@\fi
 \dimen@=\Y@c \advance\dimen@#2\relax\ifdim\dimen@>\Y@max \Y@max=\dimen@\fi
 \dimen@=\Y@c \advance\dimen@-#2\relax\ifdim\dimen@<\Y@min \Y@min=\dimen@\fi
}
%% \cubicCircleControls@@ 
\xydef@\cubicCircleControls@@{\X@origin=\z@ \Y@origin=\z@
 \X@xbase=\R@ \Y@xbase=\z@ \X@ybase=\z@ \Y@ybase=\L@
 \vfromcartesian@@1,0@\czeroEdge@\idfromc@{0@c}%
 \vfromcartesian@@0,1@\czeroEdge@\idfromc@{1@c}%
 \vfromcartesian@@-1,0@\czeroEdge@\idfromc@{2@c}%
 \vfromcartesian@@0,-1@\czeroEdge@\idfromc@{3@c}%
 \vfromcartesian@@1,\Circmagic@@ @\czeroEdge@\idfromc@{1@m}%
 \vfromcartesian@@\Circmagic@@,1@\czeroEdge@\idfromc@{2@m}%
 \vfromcartesian@@-\Circmagic@@,1@\czeroEdge@\idfromc@{3@m}%
 \vfromcartesian@@-1,\Circmagic@@ @\czeroEdge@\idfromc@{4@m}%
 \vfromcartesian@@-1,-\Circmagic@@ @\czeroEdge@\idfromc@{5@m}%
 \vfromcartesian@@-\Circmagic@@,-1@\czeroEdge@\idfromc@{6@m}%
 \vfromcartesian@@\Circmagic@@,-1@\czeroEdge@\idfromc@{7@m}%
 \vfromcartesian@@1,-\Circmagic@@ @\czeroEdge@\idfromc@{8@m}%
 }
\xydef@\doCircleQuadrant@@#1#2{\save@ \ifcase#2\relax
 \doCircleQuadrant@@@{0@c}{1@m}{2@m}{1@c}{#1}\or
 \doCircleQuadrant@@@{1@c}{3@m}{4@m}{2@c}{#1}\or
 \doCircleQuadrant@@@{2@c}{5@m}{6@m}{3@c}{#1}\or
 \doCircleQuadrant@@@{3@c}{7@m}{8@m}{0@c}{#1}\or
 \doCircleQuadrant@@@{0@c}{1@m}{2@m}{1@c}{#1}\or
 \doCircleQuadrant@@@{1@c}{3@m}{4@m}{2@c}{#1}\or
 \doCircleQuadrant@@@{2@c}{5@m}{6@m}{3@c}{#1}\or
 \doCircleQuadrant@@@{3@c}{7@m}{8@m}{0@c}{#1}\fi \leave@ }
\xydef@\doCircleQuadrant@@@#1#2#3#4#5{%
 \cfromid@{#1}\pfromc@\senter@
 \cfromid@{#2}\spushc@\cfromid@{#3}\spushc@\cfromid@{#4}%
 \connect@\crvs{#5}\relax\sinit@\sleave@}
\xydef@\dosolidcircle@#1{\let\bstartPLACE@=\relax
 \cubicCircleControls@@ 
 \doCircleQuadrant@@{#1}1
 \doCircleQuadrant@@{#1}2
 \doCircleQuadrant@@{#1}3
 \doCircleQuadrant@@{#1}4 \relax}%
\xydef@\solidcircle@{\dosolidcircle@@}
\xylet@\dosolidcircle@@=\dosolidcircle@
\xydef@\circledobjects@{\cubicCircleControls@@ 
 \setboxz@h{\expandafter\object\circleSTYLE@{}}%
 \ifdim\L@>\R@ \dimen@ii=\ht\z@ \advance\dimen@ii \dp\z@
 \ifdim\zz@\dimen@ii \dimen@ii=\wdz@\fi
 \else \dimen@ii=\wdz@ 
 \ifdim\zz@\dimen@ii \dimen@ii=\ht\z@ \advance\dimen@ii \dp\z@\fi
 \fi \ifdim\zz@\dimen@ii \dimen@ii=2\jot\fi
 \expandafter\dimen@\ifdim\L@>\R@ \twoPi@\L@\else \twoPi@\R@\fi
 \advance\dimen@.5\dimen@ii
 \count@@=\dimen@ \count@=\dimen@ii \divide\count@@\count@
 \edef\numobjects{\the\count@@}%
 \dimen@=4\p@ \divide\dimen@\numobjects\relax
 \edef\circleseparation@{\expandafter\removePT@\the\dimen@}%
 \edef\circleplace@{-\circleseparation@}\placeQuadrants@}%
\xydef@\placeQuadrants@{\DN@{\placeAllQuadrants@}%
 \ifx\onlyQuad@\undefined\else\ifx\onlyQuad@\empty\else
 \DN@{\expandafter\placeCircQuadrant@\expandafter{\onlyQuad@}}%
 \fi\fi \next@ }%
\xydef@\placeAllQuadrants@{%
 \placeCircQuadrant@{1}%
 \advance\dimen@-\p@\advance\dimen@-\circleseparation@\p@
 \edef\circleplace@{\expandafter\removePT@\the\dimen@}%
 \placeCircQuadrant@{2}%
 \advance\dimen@-\p@\advance\dimen@-\circleseparation@\p@
 \edef\circleplace@{\expandafter\removePT@\the\dimen@}%
 \placeCircQuadrant@{3}%
 \advance\dimen@-\p@\advance\dimen@-\circleseparation@\p@
 \edef\circleplace@{\expandafter\removePT@\the\dimen@}%
 \placeCircQuadrant@{4}}
\xydef@\placeCircQuadrant@#1{%
 \let\bstartPLACE@=\empty \doCircleQuadrant@@{}#1%
 \loop@
 \expandafter\dimen@\circleplace@\p@
 \advance\dimen@\circleseparation@\p@
 \edef\circleplace@{\expandafter\removePT@\the\dimen@}%
 \ifdim\dimen@<\p@ \placeCircObject@
 \repeat@ }
\xydef@\placeCircObject@{\begingroup
 \crvconnect@@ \Creset@@ \Invisible@false
 \expandafter\splinealong@\expandafter{\circleplace@}%
 \expandafter\drop\circleSTYLE@{}\endgroup }
\xydef@\buildcircle@{\save@
 \DNii@{\circledobjects@}%
 \ifx\circleSTYLE@\empty\DNii@{\solidcircle@{}}%
 \else \expandafter\DN@\expandafter{\addDASH@{}}\relax
 \ifx\next@\circleSTYLE@ \DNii@{\solidcircle@{}}%
 \else \expandafter\DN@\expandafter{\addEQ@{}}%
 \ifx\next@\circleSTYLE@ 
 \expandafter\circletemplate@\expandafter{\addEQ@{}}{}%
 \else \expandafter\DN@\expandafter{\addDASH@ 2}%
 \ifx\next@\circleSTYLE@ \DNii@{\doublecircle@{}}%
 \else \expandafter\DN@\expandafter{\addDASH@ 3}%
 \ifx\next@\circleSTYLE@ \DNii@{\triplecircle@{}}%
 \else \expandafter\expandafter\expandafter\DN@\expandafter\expandafter
 \expandafter{\expandafter\addDASH@\addDASH@{}}%
 \ifx\next@\circleSTYLE@ \DNii@{\dashedcircle@{}}%
 \else \expandafter\expandafter\expandafter\DN@\expandafter\expandafter
 \expandafter{\expandafter\addEQ@\addEQ@{}}%
 \ifx\next@\circleSTYLE@ \expandafter\expandafter\expandafter
 \circletemplate@\expandafter\expandafter\expandafter{%
 \expandafter\addEQ@\addEQ@{}}2%
 \else \expandafter\expandafter\expandafter\DN@\expandafter\expandafter
 \expandafter{\expandafter\addEQ@\addEQ@2}%
 \ifx\next@\circleSTYLE@ \expandafter\expandafter\expandafter
 \circletemplate@\expandafter\expandafter\expandafter{%
 \expandafter\addEQ@\addEQ@{}}2%
 \else \expandafter\expandafter\expandafter\DN@\expandafter\expandafter
 \expandafter{\expandafter\addEQ@\addEQ@3}%
 \ifx\next@\circleSTYLE@ \expandafter\expandafter\expandafter
 \circletemplate@\expandafter\expandafter\expandafter{%
 \expandafter\addEQ@\addEQ@{}}3%
 \else \expandafter\DN@\expandafter{\addDOT@{}}\relax
 \ifx\next@\circleSTYLE@ \DNii@{\dottedcircle@{}}%
 \else \expandafter\DN@\expandafter{\addDOT@2}\relax
 \ifx\next@\circleSTYLE@ \DNii@{\dbldottedcircle@{}}%
 \else \expandafter\DN@\expandafter{\addDOT@3}\relax
 \ifx\next@\circleSTYLE@ \DNii@{\trpldottedcircle@{}}%
 \else \DN@{:}\relax
 \ifx\next@\circleSTYLE@ \DNii@{\dbldottedcircle@{}}%
 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \nextii@ \leave@}
\xydef@\circletemplate@#1#2{\def\circleSTYLE@{\dir#2{#1}}}
\xydef@\doublecircle@#1{%
 \advance\R@-\p@ \advance\L@-\p@ \solidcircle@{}%
 \advance\R@ 2\p@ \advance\L@ 2\p@ \solidcircle@{}}
\xydef@\triplecircle@#1{%
 \advance\R@-2\p@ \advance\L@-2\p@ \solidcircle@{}%
 \advance\R@ 2\p@ \advance\L@ 2\p@ \solidcircle@{}%
 \advance\R@ 2\p@ \advance\L@ 2\p@ \solidcircle@{}}
\xydef@\dottedcircle@#1{%
 \expandafter\def\expandafter\circleSTYLE@\expandafter{%
 \zerodot@i}%
 \circledobjects@}
\xydef@\dashedcircle@#1{%
 \expandafter\def\expandafter\circleSTYLE@\expandafter{\zerodash@i}%
 \circledobjects@}
\xydef@\dbldottedcircle@#1{%
 \advance\R@-\p@ \advance\L@-\p@ \dottedcircle@{}%
 \advance\R@ 2\p@ \advance\L@ 2\p@ \dottedcircle@{}}
\xydef@\trpldottedcircle@{%
 \advance\R@-2\p@ \advance\L@-2\p@ \dottedcircle@{}%
 \advance\R@ 2\p@ \advance\L@ 2\p@ \dottedcircle@{}%
 \advance\R@ 2\p@ \advance\L@ 2\p@ \dottedcircle@{}}
{\xyuncatcodes \gdef\next{=<.75\jot>{\zerodot}}}
\xylet@\zerodot@i=\next
{\dimen0=2\xydashl@ \xyuncatcodes 
\expandafter\gdef\expandafter\next\expandafter{\expandafter
 =\expandafter<\the\dimen0 >_\dir{|}}}
\xylet@\zerodash@i=\next
{\xyuncatcodes\gdef\next{--}}
\xylet@\dashcorntemp@@=\next
{\xyuncatcodes\gdef\next{.}}
\xylet@\dotcorntemp@@=\next
\xydef@\dotcorner@#1{%
 \expandafter\circleCorner@\expandafter{\dotcorntemp@@}{#1}}%
\xydef@\dashcorner@#1{%
 \expandafter\circleCorner@\expandafter{\dashcorntemp@@}{#1}}
\xydef@\circleCorner@#1#2{\setboxz@h\bgroup 
 \edef\next{#2\relax\R@=\the\R@\relax\L@=\R@ }%
 \expandafter\xycircle@\next @{#1}%
 \ifcase#2\or \setboxz@h{\lower\R@\boxz@\kern\X@c}%
 \or \setboxz@h{\kern-\R@\lower\R@\boxz@\kern\R@\kern\X@c}%
 \or \setboxz@h{\kern-\R@\lower\R@\boxz@\kern\R@\kern\X@c}%
 \or \setboxz@h{\lower\R@\boxz@\kern\X@c}\fi
 \wdz@=\R@ \ht\z@=\R@ \dp\z@=\R@ \boxz@
 }
\xydef@\qspline{\hbox\bgroup\xy@spline@}
\xydef@\xy@spline@#1#{\if\sempty@ 
 \DN@{\let\bstartPLACE@=\relax \crvs@{}}%
 \else\DN@{\xy@spline@i{#1}}\fi \next@ }%
\xydef@\xy@spline@i#1#2{\def\splineSTYLE@{#2}%
 \DN@{\xy@spline@ii}\DNii@{#1}%
 \ifx\nextii@\empty\DN@{\xy@spline@ii@@}\fi \next@ }
\xydef@\xy@spline@ii{\save@ \cfromp@\idfromc@{@p}%
 \enter@\cplusthec@ \count@@=\s@top\advance\count@@\m@ne
 \cfroms@{\count@@}\leave@
 \divide\X@c\tw@ \divide\Y@c\tw@\czeroEdge@ \idfromc@{@c}%
 \expandafter\doSplineStraight@\expandafter{\splineSTYLE@}%
 \count@=\@ne \edef\next@{\the\count@}%
 \ifx\next@\s@top\DN@{\xy@spline@iv}\else\DN@{\xy@spline@iii}\fi 
 \next@ }
\xylet@\xy@spline@ii@@=\xy@spline@ii
\xydef@\xy@spline@iii{\crv@cnt@=\s@top 
 \loop \advance\crv@cnt@\m@ne \xy@spline@g \ifnum\crv@cnt@>\@ne\repeat
 \xy@spline@iv}
\xydef@\xy@spline@g{\cfromid@{@c}\idfromc@{@p}%
 \count@@=\crv@cnt@\cfroms@{\count@@}\idfromc@{@m}%
 \enter@\cplusthec@ \count@@=\crv@cnt@ \advance\count@@\m@ne
 \cfroms@{\count@@}\leave@
 \divide\X@c\tw@ \divide\Y@c\tw@ \czeroEdge@\idfromc@{@c}%
 \expandafter\doSplineSegment@\expandafter{\splineSTYLE@}}
\xydef@\xy@spline@iv{\cfromid@{@c}\idfromc@{@p}%
 \cfroms@{\z@}\idfromc@{@m}\leave@ \save@
 \enter@\cplusthec@ \cfromid@{@m}\leave@
 \divide\X@c\tw@ \divide\Y@c\tw@ \czeroEdge@\idfromc@{@c}%
 \expandafter\doSplineSegment@\expandafter{\splineSTYLE@}%
 \xy@spline@v }
\xydef@\xy@spline@v{\cfromid@{@c}\idfromc@{@p}%
 \leave@ \save@ \idfromc@{@c}%
 \expandafter\doSplineStraight@\expandafter{\splineSTYLE@}%
 \xy@spline@x }
\xydef@\xy@spline@x{\leave@
 \def\Drop@@{\splineDrop@}%
 \def\Connect@@{\straight@\relax\splineConnect@}%
 \OBJECT@x}
\xydef@\splineDrop@{\ifInvisible@\setboxz@h{}%
 \else\setboxz@h{\kern-\the\X@c\raise-\the\Y@c\boxz@}\fi
 \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@ }
\xydef@\splineConnect@{%
 \ifInvisible@\else\box\lastobjectbox@\fi }%
\xydef@\doSplineStraight@#1{\begingroup \sinit@
 \cfromid@{@p}\pfromc@\cfromid@{@c}%
 \connect@\crvs{#1}\relax\sleave@\endgroup }
\xydef@\doSplineSegment@#1{\begingroup \sinit@
 \cfromid@{@p}\pfromc@\senter@\cfromid@{@m}\spushc@\cfromid@{@c}%
 \connect@\crvs{#1}\relax\sinit@\sleave@\endgroup }
\xyendinput

xyframe.tex
%% xyframe.tex from $Id: xyframe.doc,v 3.2 1995/09/19 18:22:27 kris Exp $
%%
%% Xy-pic ``Frames and Brackets'' extension.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined \input xy \fi
\xyprovide{frame}{Frame and Bracket extension}{\stripRCS$Revision: 3.2 $}%
 {Kristoffer H.~Rose}{kris@diku.dk}%
 {Computer Science, University of Copenhagen, Universitetsparken~1,
 DK--2100 K{\o}benhavn~{\O}}
\xydef@\frm{\hbox{}\dimen@=\L@c \advance\dimen@\R@c \wdz@=\dimen@
 \ht\z@=\U@c \dp\z@=\D@c \dimen@=\U@c \advance\dimen@\D@c
 \ifdim\wdz@=\z@ \def\Leftness@{.5}\else \quotient@\Leftness@\L@c\wdz@ \fi
 \ifdim\dimen@=\z@ \def\Upness@{.5}\else \quotient@\Upness@\U@c\dimen@ \fi
 \expandafter\Edge@c\expandafter{\prevEdge@@}\let\frmradius@@=\z@
 \def\Drop@@{}%
 \def\Connect@@{\xy@@{\save@\cmerge@\Y@p\X@p\D@p\U@p\L@p\R@p\Drop@@}\restore}%
 \xyFN@\frm@i}
\xylet@\frmradius@@=\z@
\xydef@\frm@i{%
 \addLT@\ifx\next \addGT@{\addLT@\DN@##1}{\def\frmradius@@{##1}\xyFN@\frm@i}%
 \else \DN@##1##{\frm@{##1}}\fi \next@}
\xydef@\frm@#1#2{\DNii@{frm#1{#2}}%
 \expandafter\let\expandafter\next@\csname\codeof\nextii@\endcsname
 \ifx\next@\relax \DNii@{frm{#2}}%
 \expandafter\let\expandafter\next@\csname\codeof\nextii@\endcsname
 \ifx\next@\relax \let\next@=\frm@generic \fi\fi \next@}
\xydef@\frm@generic{\xyerror@{No generic frames yet!}{}}
\xydef@\frmDrop@#1{%
 \ifx\frmradius@@\z@ \addtoDrop@@{\let\frmradius@@=\z@ #1}%
 \else \expandafter\addtoDrop@@\expandafter{%
 \expandafter\def\expandafter\frmradius@@\expandafter{\frmradius@@}#1}\fi}
\xydef@\EdgefromtheEdge@{%
 \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c
 \Edge@c={\expandafter\noexpand\the\Edge@c}}
\xydef@\prevEdgefromtheEdge@{%
 \U@c=\the\U@c \D@c=\the\D@c \L@c=\the\L@c \R@c=\the\R@c
 \noexpand\def\noexpand\prevEdge@@{\expandafter\noexpand\the\Edge@c}}
\xydef@\addtoDrop@@#1{%
 \expandafter\def\expandafter\Drop@@\expandafter{\Drop@@#1}}
\xydef@\addbeforeDrop@@#1{\DNii@{#1}%
 \expandafter\DN@\expandafter{\expandafter\nextii@\Drop@@}%
 \expandafter\expandafter\expandafter\def
 \expandafter\expandafter\expandafter\Drop@@
 \expandafter\expandafter\expandafter{\next@}}
\xydefcsname@{frm{}}{}
\xyletcsnamecsname@{frm[]{}}{frm{}}
\xyletcsnamecsname@{frm[o]{}}{frm{}}
\xydefcsname@{frm{.}}{\frmDrop@{\let\zerocorner=\framezerodot@@
 \let\framehfill=\frm@doth@@ \let\framevfill=\frm@dotv@@
 \framed@@{\frmradius@@}}}
\xyletcsnamecsname@{frm[]{.}}{frm{.}}
\xydef@\frm@doth@@{\setboxz@h{\kern5\B@\framezerodot@@\kern5\B@}\ht\z@=\B@
 \dp\z@=\B@\kern5\B@\xleaders\boxz@\hss\kern5\B@}
\xydef@\frm@dotv@@{\setboxz@h to2\B@{\hss\framezerodot@@\hss}\ht\z@=5\B@
 \dp\z@=5\B@\kern5\B@\xleaders\boxz@\vss\kern5\B@}
\xyletcsnamecsname@{frm{..}}{frm{.}}
\xylet@\framezerodot@@=\zerodot
\xydefcsname@{frm{-}}{\frmDrop@{\framed@\frmradius@@}}
\xyletcsnamecsname@{frm[]{-}}{frm{-}}
\xydef@\framed@{\let\zerocorner=\framezerodot@@
 \let\framehfill=\frm@solidh@@ \let\framevfill=\frm@solidv@@ \framed@@}
\xylet@\framesetthick@=\relax
\xydef@\frm@solidh@@{\framesetthick@\leaders\hrule height\B@ depth\B@\hfill}
\xydef@\frm@solidv@@{\framesetthick@\leaders\vrule width2\B@\vfill}
\xydefcsname@{frm{=}}{\frmDrop@{\framed@\frmradius@@
 {\advance\L@c-2\p@ \advance\R@c-2\p@ \advance\U@c-2\p@ \advance\D@c-2\p@
 \dimen@=\frmradius@@
 \ifdim\dimen@>2\p@ \advance\dimen@-2\p@ \else \dimen@=\z@\fi
 \framed@\dimen@}}}
\xyletcsnamecsname@{frm[]{=}}{frm{=}}
\xydef@\framesetthick@line{\B@=.5\xylinethick@}
\xydef@\frm@thickc@@{\hbox{\framesetthick@line
 \vrule height.5\B@ depth.5\B@ width\B@}}
\xywithoption{line}{%
 \let\framezerodot@@\frm@thickc@@ \let\framesetthick@=\framesetthick@line}
\xydef@\framed@@#1{\setboxz@h{\R@=#1\relax 
 \dimen@=\L@c \advance\dimen@\R@c \dimen@ii=\U@c \advance\dimen@ii\D@c
 \ifdim.5\dimen@<\R@ \R@=.5\dimen@ \fi
 \ifdim.5\dimen@ii<\R@ \R@=.5\dimen@ii \fi
 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@-\D@c
 \ifdim\R@<\p@\else \cirrestrict@@ \fi
 \dimen@=2\R@ \advance\dimen@-\L@c \advance\dimen@-\R@c
 \ifdim\dimen@>\z@ \advance\A@-.5\dimen@ \fi
 \dimen@=2\R@ \advance\dimen@-\U@c \advance\dimen@-\D@c
 \ifdim\dimen@>\z@ \advance\B@-.5\dimen@ \fi
 \kern\A@ \raise\B@\vbox to \dimen@ii{\framed@body@@}}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
\xydef@\framed@body@{%
 \advance\dimen@ii.22\p@ \advance\dimen@-.2\p@ 
 \setboxz@h{\corn@@4\R@}\A@=-.5\wdz@ \B@=.5\xydashw@
 \dimen@=\L@c \advance\dimen@\R@c \advance\dimen@-.2\p@
 \setboxz@h to\dimen@{\kern\A@ \boxz@ \framehfill\corn@@3\R@\kern\A@}%
 \advance\dimen@ii-\dp\z@ \kern-\ht\z@ \nointerlineskip\boxz@
 \dimen@=\L@c \advance\dimen@\R@c \advance\dimen@-.2\p@
 \setboxz@h to\dimen@{\kern\A@\corn@@1\R@\framehfill\corn@@2\R@\kern\A@}%
 \advance\dimen@ii-\ht\z@
 \dimen@=\L@c \advance\dimen@\R@c \advance\dimen@.2\p@
 \nointerlineskip\hbox to\dimen@{%
 \setbox\z@=\vbox to\dimen@ii{\framevfill}\kern-.5\wdz@\copy\z@
 \hss \copy\z@\kern-.5\wdz@ }%
 \nointerlineskip\boxz@ \vss \kern\z@}
\xylet@\framed@body@@=\framed@body@
\xylet@\zerocorner=\framezerodot@@
\xydef@\solidcorner@#1#2{\hbox\bgroup \R@=#2\relax
 \ifdim\R@<\p@ \zerocorner
 \else \cirrestrict@@ \multiply\count@8
 \setboxz@h{\corn@x@@{#1}}\dimen@=\wdz@
 \ifcase#1\or \ht\z@=\z@ \kern\dimen@ \raise\dimen@\boxz@ 
 \or \ht\z@=\z@ \raise\dimen@\boxz@ \kern\dimen@
 \or \dp\z@=\z@ \lower\dimen@\boxz@ \kern\dimen@
 \or \dp\z@=\z@ \kern\dimen@ \lower\dimen@\boxz@ \fi
 \vrule height\dimen@ depth\dimen@ width\z@\fi
 \edef\tmp@{\egroup \U@c=\the\dimen@}\tmp@ \D@c=\U@c \L@c=\U@c \R@c=\U@c
 \Edge@c={\circleEdge}\ignorespaces}
\xydef@\corn@x@#1{\ifcase#1\or
 \circhar@@\z@ \circhar@@\@ne\or\circhar@@\tw@ \circhar@@3\or
 \circhar@@5\circhar@@4\or\circhar@@7\circhar@@6\fi}
\xylet@\corn@x@@=\corn@x@
\xydef@\corn@@{\DN@{\solidcorner@}%
 \ifx\framehfill\frm@doth@@ \DN@{\let\cirrestrict@@=\relax
 \let\corn@x@@=\dotcorner@@ \let\zerodot=\framezerodot@@
 \solidcorner@ }%
 \else\ifx\framehfill\frm@dashh@@ \DN@{\let\cirrestrict@@=\relax
 \let\corn@x@@=\dashcorner@@ \let\zerodot=\framezerodot@@
 \solidcorner@ }%
 \fi\fi \next@}
\xydef@\dotcorner@@{\dotcorner@}
\xydef@\dashcorner@@{\dashcorner@}
\xydefcsname@{frm{--}}{%
 \frmDrop@{\let\zerocorner=\framezerodot@@ 
 \let\framehfill=\frm@dashh@@ \let\framevfill=\frm@dashv@@
 \framed@@\frmradius@@}}
\xyletcsnamecsname@{frm[]{--}}{frm{--}}
\xydef@\frm@dashh@@{\setboxz@h{\dashhfillchar}%
 \ht\z@=\B@ \dp\z@=\B@ \wdz@=2\xydashl@
 \copy\z@ \xleaders\copy\z@\hss \boxz@\kern-\xydashl@}
\xydef@\frm@dashv@@{\setboxz@h to2\B@{\hss\dashvfillchar\hss}\ht\z@=\z@
 \dp\z@=2\xydashl@ \nointerlineskip\copy\z@ \xleaders\copy\z@\vss
 \nointerlineskip\boxz@\kern-\xydashl@}%
\xydef@\dashhfillchar{{\rDirection@\xydashl@ \line@@}}
\xydef@\dashvfillchar{{\dDirection@\xydashl@ \line@@}}
\xydefcsname@{frm{o-}}{%
 \ifdim\frmradius@@<2\xydashl@\relax \dimen@=.8\xydashl@
 \expandafter\def\expandafter\frmradius@@\expandafter{\the\dimen@}\fi
 \frmDrop@{\let\zerocorner=\framezerodot@@ 
 \let\framehfill=\frm@rddashh@@ \let\framevfill=\frm@rddashv@@
 \framed@@\frmradius@@}}%
\xydef@\frm@rddashh@@{\setboxz@h{\kern\xydashl@\dashhfillchar}%
 \ht\z@=\B@ \dp\z@=\B@ \copy\z@ \xleaders\copy\z@\hss \boxz@ \kern\xydashl@}
\xydef@\frm@rddashv@@{\ifdim\dimen@ii<2\xydashl@\else
 \setbox\z@=\vbox to2\xydashl@{\hbox to2\B@{\hss\dashvfillchar\hss}\vss}%
 \kern\xydashl@ \copy\z@ \xleaders\copy\z@\vss
 {\ifdim\dimen@ii<2\xydashl@\else\aftergroup\boxz@\fi}\fi}
\xydefcsname@{frm{,}}{%
 \ifx\frmradius@@\z@ \shaded@{1.2\p@}\else \shaded@\frmradius@@ \fi}
\xydef@\shaded@#1{\frmDrop@{\R@=#1\relax
 {\advance\X@c\R@ \advance\Y@c-\D@c \U@c=\z@ \D@c=\R@ \blacked@}%
 {\advance\X@c\R@c \advance\Y@c-\R@ \L@c=\z@ \R@c=\R@ \blacked@}}}
\xydefcsname@{frm{-,}}{\addtoDrop@@{\drop\frm{-}\drop\frm{,}}}
\xydef@\blacked@{\setboxz@h{%
 \A@=\X@c \advance\A@-\L@c \dimen@=\L@c \advance\dimen@\R@c
 \B@=\Y@c \advance\B@-\D@c \dimen@ii=\Y@c \advance\dimen@ii\U@c
 \advance\A@-.5\xydashw@
 \kern\A@ \blacked@@ }%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
\xydef@\bblacked@{\setboxz@h{%
 \dimen@=\L@c \advance\dimen@\R@c \B@=-\D@c \dimen@ii=\U@c
 \kern-\L@c \blacked@@ \kern-\dimen@ \kern\L@c}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
\xydef@\blacked@@{\vrule width\dimen@ depth-\B@ height\dimen@ii}
\xydefcsname@{frm{o}}{%
 \ifx\frmradius@@\z@
 \frmDrop@{\dimen@=.5\L@c \advance\dimen@.5\R@c
 \let\framehfill=\frm@solidh@@ \let\framevfill=\frm@solidv@@
 \circled@\dimen@}%
 \else
 \frmDrop@{\let\framehfill=\frm@solidh@@
 \let\framevfill=\frm@solidv@@ \circled@\frmradius@@}%
 \fi}
\xydefcsname@{frm{oo}}{%
 \ifx\frmradius@@\z@
 \frmDrop@{\dimen@=.5\L@c \advance\dimen@.5\R@c
 \let\framehfill=\frm@solidh@@ \let\framevfill=\frm@solidv@@
 {\circled@\dimen@}\advance\dimen@-2.1\p@ \circled@\dimen@}%
 \else
 \frmDrop@{\dimen@=\frmradius@@
 \let\framehfill=\frm@solidh@@ \let\framevfill=\frm@solidv@@
 {\circled@\dimen@}\advance\dimen@-2.1\p@ \circled@\dimen@}%
 \fi}
\xydef@\circled@#1{\setboxz@h\bgroup \R@=#1\relax 
 \setboxz@h{\vbox{\circled@x@@}}%
 \A@=\X@c \advance\A@-.5\wd\z@
 \B@=\Y@c \advance\B@-.5\ht\z@ \advance\B@.5\dp\z@ \advance\B@.2\p@
 \edef\tmp@{\egroup\dimen@=\the\wdz@}%
 \kern\A@ \raise\B@\boxz@
 \tmp@ \divide\dimen@4 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
\xydef@\circled@x@{\hbox{\corn@@4\R@ \corn@@3\R@}%
 \nointerlineskip\hbox{\corn@@1\R@ \corn@@2\R@}}
\xylet@\circled@x@@=\circled@x@
\xydefcsname@{frm{.o}}{%
 \ifx\frmradius@@\z@ \frmDrop@{\let\framehfill=\frm@doth@@ 
 \dimen@=.5\L@c \advance\dimen@.5\R@c \circled@\dimen@}%
 \else
 \frmDrop@{\let\framehfill=\frm@doth@@ \circled@\frmradius@@}%
 \fi}
\xydefcsname@{frm{-o}}{%
 \ifx\frmradius@@\z@ \frmDrop@{\let\framehfill=\frm@dashh@@
 \dimen@=.5\L@c \advance\dimen@.5\R@c \circled@\dimen@}%
 \else
 \frmDrop@{\let\framehfill=\frm@dashh@@ \circled@\frmradius@@}%
 \fi}
\xydefcsname@{frm{e}}{\ellipse@whichfrm@\ellipsesolidframed@}%
\xydefcsname@{frm{.e}}{\ellipse@whichfrm@\ellipsedotframed@}%
\xydefcsname@{frm{-e}}{\ellipse@whichfrm@\ellipsedashframed@}%
\xydefcsname@{frm{ee}}{\ellipse@whichdblfrm@\ellipsesolidframed@}%
\xydefcsname@{frm2{.e}}{\ellipse@whichdblfrm@\ellipsedotframed@}%
\xydefcsname@{frm2{-e}}{\ellipse@whichdblfrm@\ellipsedashframed@}%
\xyletcsnamecsname@{frm[o]{-}}{frm{e}}
\xyletcsnamecsname@{frm[o]{=}}{frm{ee}}
\xyletcsnamecsname@{frm[o]{.}}{frm{.e}}
\xyletcsnamecsname@{frm[o]{--}}{frm{-e}}
\xydef@\ellipse@whichfrm@#1{%
 \ifx\frmradius@@\z@
 \frmDrop@{#1\dimen@=.5\L@c \advance\dimen@.5\R@c
 \dimen@ii=.5\U@c \advance\dimen@ii.5\D@c
 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}\next@ }%
 \else
 \frmDrop@{#1\expandafter\ellipsed@i@\frmradius@@,,@@}%
 \fi}
\xydef@\ellipse@whichdblfrm@#1{%
 \ifx\frmradius@@\z@
 \frmDrop@{#1\dimen@=.5\L@c \advance\dimen@.5\R@c
 \dimen@ii=.5\U@c \advance\dimen@ii.5\D@c
 \edef\next@{\noexpand\ellipsed@e@{\the\dimen@}{\the\dimen@ii}}\next@ }%
 \else
 \frmDrop@{#1\expandafter\ellipsed@ei@\frmradius@@,,@@}%
 \fi}
\xydef@\ellipsed@i@#1,#2,#3@@{\DNii@{,}\DN@{#3}%
 \ifx\next@\nextii@
 \dimen@=#1\relax \dimen@ii=#2\relax
 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}%
 \else \ifx\next@\empty \DN@{#2}%
 \ifx\next@\empty \DN@{#1}%
 \dimen@=.5\L@c \advance\dimen@.5\R@c
 \dimen@ii=.5\U@c \advance\dimen@ii.5\D@c
 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}%
 \else \dimen@=#1\relax
 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}%
 \fi
 \else\xywarning@{ignoring extra tokens in elliptical frame: #3 }%
 \dimen@=#1\relax \dimen@ii=#2\relax 
 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}%
 \fi\fi \next@ }
\xydef@\ellipsed@ei@#1,#2,#3@@{\DNii@{,}\DN@{#3}%
 \ifx\next@\nextii@
 \dimen@=#1\relax \dimen@ii=#2\relax 
 \edef\next@{\noexpand\ellipsed@e@{\the\dimen@}{\the\dimen@ii}}%
 \else \ifx\next@\empty \DN@{#2}%
 \ifx\next@\empty \DN@{#1}%
 \dimen@=.5\L@c \advance\dimen@.5\R@c
 \dimen@ii=.5\U@c \advance\dimen@ii.5\D@c
 \edef\next@{\noexpand\ellipsed@e@{\the\dimen@}{\the\dimen@ii}}%
 \else 
 \dimen@=#1\relax 
 \edef\next@{\noexpand\ellipsed@e@{\the\dimen@}{\the\dimen@}}%
 \fi
 \else\xywarning@{ignoring extra tokens in elliptical frame: #3 }%
 \dimen@=#1\relax \dimen@ii=#2\relax 
 \edef\next@{\noexpand\ellipsed@e@{\the\dimen@}{\the\dimen@ii}}%
 \fi\fi \next@ }
\xydef@\ellipsed@e@#1#2{%
 \dimen@=#1\relax \dimen@ii=#2\relax 
 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}\next@ 
 \dimen@=#1\relax \dimen@ii=#2\relax 
 \ifdim\dimen@>2\p@ \advance\dimen@-2\p@ \else \dimen@=\z@\fi
 \ifdim\dimen@ii>2\p@ \advance\dimen@ii-2\p@ \else \dimen@ii=\z@\fi
 \edef\next@{\noexpand\ellipsed@{\the\dimen@}{\the\dimen@ii}}\next@ }%
\xydef@\ellipsed@#1#2{\setboxz@h\bgroup \relax
 \setboxz@h{\vbox{\ellipsed@x@@{#1}{#2}}}%
 \A@=\X@c \advance\A@-.5\wd\z@
 \B@=\Y@c \advance\B@-.5\ht\z@ \advance\B@.5\dp\z@ \advance\B@.2\p@
 \edef\tmp@{\egroup\dimen@=\the\wdz@}%
 \kern\A@ \raise\B@\boxz@
 \tmp@ \divide\dimen@4 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}
\xydef@\ellipsed@i#1#2{{\R@c=#1\relax\L@c=\R@c
 \U@c=#2\relax\D@c=\U@c \ellipsed@{#1}{#2}}}
\xydef@\ellipsed@x@#1#2{\R@=#1\relax \advance\R@#2\relax
 \divide\R@\tw@ \circled@x@@ }
\xylet@\ellipsed@x@@=\ellipsed@x@
\xydef@\ellipsesolidframed@{%
 \let\framehfill=\frm@solidh@@ \let\framevfill=\frm@solidv@@}
\xydef@\ellipsedotframed@{%
 \let\framehfill=\frm@doth@@ \let\framevfill=\frm@dotv@@}
\xydef@\ellipsedashframed@{%
 \let\framehfill=\frm@dashh@@ \let\framevfill=\frm@dashv@@}
\xydefcsname@{frm{\{}}{\addtoDrop@@{\lbraced}}
\xydefcsname@{frm{\}}}{\addtoDrop@@{\rbraced}}
\xydefcsname@{frm{^\}}}{\addtoDrop@@{\ubraced}}
\xydefcsname@{frm{_\}}}{\addtoDrop@@{\dbraced}}
\xydef@\dbraced{\xy@@{\setboxz@h{%
 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@-\D@c
 \setboxz@h{$\m@th\bracelu$}\dimen@=2\wdz@ \advance\B@-.5\ht\z@
 \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
 \ifdim\L@c<\dimen@ \advance\A@-\dimen@ \advance\A@\L@c \L@c=\dimen@ \fi
 \advance\A@-.25pt
 \kern\A@\raise\B@\hbox{%
 \hbox to\L@c{$\m@th\bracelu\leaders\vrule\hfil\bracerd$}%
 \kern.5pt
 \hbox to\R@c{$\m@th\braceld\leaders\vrule\hfil\braceru$}}}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
\xydef@\ubraced{\xy@@{\setboxz@h{%
 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@\U@c
 \setboxz@h{$\m@th\bracelu$}\dimen@=2\wdz@
 \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
 \ifdim\L@c<\dimen@ \advance\A@-\dimen@ \advance\A@\L@c \L@c=\dimen@ \fi
 \advance\A@-.25pt
 \kern\A@\raise\B@\hbox{%
 \hbox to\L@c{$\m@th\braceld\leaders\vrule\hfil\braceru$}%
 \kern.5pt
 \hbox to\R@c{$\m@th\bracelu\leaders\vrule\hfil\bracerd$}}}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
{\catcode`\"=12
 \global\mathchardef\braceur="338
 \global\mathchardef\braceul="339
 \global\mathchardef\bracedr="33A
 \global\mathchardef\bracedl="33B
 \global\mathchardef\bracecl="33C
 \global\mathchardef\bracecr="33D
 \global\mathchardef\bracec="33E }
\xydef@\lbraced{\xy@@{\setboxz@h{%
 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@-\D@c
 \setboxz@h{$\m@th\bracecl$}\dimen@ii=\dp\z@ \advance\A@-.5\wdz@
 \setboxz@h{$\m@th\bracec$}\dimen@=\dp\z@
 \ifdim\U@c<.5\dimen@ \U@c=.5\dimen@ \fi
 \ifdim\D@c<.5\dimen@ \advance\B@-.5\dimen@ \advance\B@\D@c \D@c=.5\dimen@ \fi
 \advance\U@c.6\p@ \advance\D@c.6\p@ \advance\B@-.6\p@
 \kern\A@\raise\B@\vbox{\vbox to\U@c{%
 \nointerlineskip\hbox{$\m@th\braceur$}%
 \kern-.61\dimen@ \cleaders\copy\z@\vfil \kern-.4\dimen@
 \nointerlineskip\hbox{$\m@th\bracecl$}\kern-.5\dimen@ii}%
 \nointerlineskip\vbox to\D@c{\kern.5\dimen@ii
 \kern-.4\dimen@ \cleaders\copy\z@\vfil \kern-.61\dimen@
 \nointerlineskip\hbox{$\m@th\bracedr$}\kern\z@}}}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
\xydef@\rbraced{\xy@@{\setboxz@h{%
 \A@=\X@c \advance\A@\R@c \B@=\Y@c \advance\B@-\D@c
 \setboxz@h{$\m@th\bracecr$}\dimen@ii=\dp\z@ \advance\A@-.5\wdz@
 \setboxz@h{$\m@th\bracec$}\dimen@=\dp\z@
 \ifdim\U@c<.5\dimen@ \U@c=.5\dimen@ \fi
 \ifdim\D@c<.5\dimen@ \advance\B@-.5\dimen@ \advance\B@\D@c \D@c=.5\dimen@ \fi
 \advance\U@c.6\p@ \advance\D@c.6\p@ \advance\B@-.6\p@
 \kern\A@\raise\B@\vbox{\vbox to\U@c{%
 \nointerlineskip\hbox{$\m@th\braceul$}%
 \kern-.61\dimen@ \cleaders\copy\z@\vfil \kern-.4\dimen@
 \nointerlineskip\hbox{$\m@th\bracecr$}\kern-.5\dimen@ii}%
 \nointerlineskip\vbox to\D@c{\kern.5\dimen@ii
 \kern-.4\dimen@ \cleaders\copy\z@\vfil \kern-.61\dimen@
 \nointerlineskip\hbox{$\m@th\bracedl$}\kern\z@}}}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
\xydefcsname@{frm{(}}{\addtoDrop@@{\lparenthesized}}
\xydefcsname@{frm{)}}{\addtoDrop@@{\rparenthesized}}
\xydefcsname@{frm{^)}}{\addtoDrop@@{\uparenthesized}}
\xydefcsname@{frm{_)}}{\addtoDrop@@{\dparenthesized}}
\xydef@\dparenthesized{\xy@@{\setboxz@h{%
 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@-\D@c
 \setboxz@h{$\m@th\bracelu$}\dimen@=2\wdz@ \advance\B@-.5\ht\z@
 \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
 \ifdim\L@c<\dimen@ \advance\A@-\dimen@ \advance\A@\L@c \L@c=\dimen@ \fi
 \dimen@=\L@c \advance\dimen@\R@c
 \kern\A@\raise\B@\hbox to\dimen@{%
 $\m@th\bracelu\leaders\vrule\hfil\braceru$}}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
\xydef@\uparenthesized{\xy@@{\setboxz@h{%
 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@\U@c
 \setboxz@h{$\m@th\bracelu$}\dimen@=2\wdz@
 \ifdim\R@c<\dimen@ \R@c=\dimen@ \fi
 \ifdim\L@c<\dimen@ \advance\A@-\dimen@ \advance\A@\L@c \L@c=\dimen@ \fi
 \dimen@=\L@c \advance\dimen@\R@c
 \kern\A@\raise\B@\hbox to\dimen@{%
 $\m@th\braceld\leaders\vrule\hfil\bracerd$}}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
\xydef@\lparenthesized{\xy@@{\setboxz@h{%
 \A@=\X@c \advance\A@-\L@c \B@=\Y@c \advance\B@-\D@c
 \setboxz@h{$\m@th\bracecr$}\dimen@ii=\dp\z@ \advance\A@-.5\wdz@
 \setboxz@h{$\m@th\bracec$}\dimen@=\dp\z@
 \ifdim\U@c<.5\dimen@ \U@c=.5\dimen@ \fi
 \ifdim\D@c<.5\dimen@ \advance\B@-.5\dimen@ \advance\B@\D@c \D@c=.5\dimen@ \fi
 \advance\U@c.6\p@ \advance\D@c.6\p@ \advance\B@-.6\p@
 \dimen@ii\U@c \advance\dimen@ii\D@c
 \kern\A@\raise\B@\vbox to \dimen@ii{%
 \nointerlineskip\hbox{$\m@th\braceur$}%
 \kern-.61\dimen@ \cleaders\copy\z@\vfil \kern-.61\dimen@
 \nointerlineskip\hbox{$\m@th\bracedr$}\kern\z@}}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
\xydef@\rparenthesized{\xy@@{\setboxz@h{%
 \A@=\X@c \advance\A@\R@c \B@=\Y@c \advance\B@-\D@c
 \setboxz@h{$\m@th\bracecr$}\dimen@ii=\dp\z@ \advance\A@-.5\wdz@
 \setboxz@h{$\m@th\bracec$}\dimen@=\dp\z@
 \ifdim\U@c<.5\dimen@ \U@c=.5\dimen@ \fi
 \ifdim\D@c<.5\dimen@ \advance\B@-.5\dimen@ \advance\B@\D@c \D@c=.5\dimen@ \fi
 \advance\U@c.6\p@ \advance\D@c.6\p@ \advance\B@-.6\p@
 \dimen@ii\U@c \advance\dimen@ii\D@c
 \kern\A@\raise\B@\vbox to \dimen@ii{%
 \nointerlineskip\hbox{$\m@th\braceul$}%
 \kern-.61\dimen@ \cleaders\copy\z@\vfil \kern-.61\dimen@
 \nointerlineskip\hbox{$\m@th\bracedl$}\kern\z@}}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@}}
\xydefcsname@{frm{*}}{%
 \expandafter\frmDrop@\expandafter{%
 \expandafter\def\expandafter\prevEdge@@\expandafter{\prevEdge@@}%
 \filled@\frmradius@@\empty}}
\xydefcsname@{frm{**}}{%
 \expandafter\frmDrop@\expandafter{%
 \expandafter\def\expandafter\prevEdge@@\expandafter{\prevEdge@@}%
 \filled@\frmradius@@\relax}}
\xydef@\filled{\DN@{%
 \addLT@\ifx \next
 \addGT@{\addLT@\DN@####1}{\xy@@{\filled@{####1}\empty}}%
 \else \DN@{\xy@@{\filled@\z@}}%
 \fi\next@}\xyFN@\next@}
\xydef@\Filled{\DN@{%
 \addLT@\ifx \next
 \addGT@{\addLT@\DN@####1}{\xy@@{\filled@{####1}\relax}}%
 \else \DN@{\xy@@{\filled@\z@}}%
 \fi\next@}\xyFN@\next@}
\xydef@\filled@#1{\R@=#1\relax 
 \expandafter\DNii@\expandafter{\prevEdge@@}%
 \DN@{\rectangleEdge}\ifx\next@\prevEdge@@
 \ifdim\R@=\z@ \DN@{\filled@Rectangle@}%
 \else \DN@{\filled@Oval@}\fi
 \else \DN@{\circleEdge}\ifx\next@\prevEdge@@
 \ifdim\R@=\z@ \DN@{\filled@Ellipse@}%
 \else \DN@{\restR@max\filled@Circle@}\fi
 \else 
 \ifdim\R@=\z@ \DN@{\filled@Rectangle@}%
 \else \DN@{\filled@Circle@}\fi
 \fi\fi \next@ }
\xydef@\restR@max{%
 \dimen@=\L@c\advance\dimen@\R@c
 \dimen@ii=\U@c \advance\dimen@ii\D@c
 \ifdim\dimen@ii>\dimen@ \dimen@=\dimen@ii\fi
 \ifdim\dimen@>\z@ \divide\dimen@\tw@
 \ifdim\R@>\dimen@\R@=\dimen@\fi\fi }
\xylet@\filledRectangle@@=\bblacked@
\xylet@\filledCircle@@=\bblacked@
\xylet@\filledEllipse@@=\bblacked@
\xylet@\filledOval@@=\bblacked@
\xydef@\filled@Region@#1#2{\setboxz@h\bgroup 
 \setboxz@h{\vbox{#1#2\empty}}%
 \A@=\X@c \advance\A@-.5\wd\z@
 \B@=\Y@c \advance\B@-.5\ht\z@ \advance\B@.5\dp\z@ 
 \edef\tmp@{\egroup\dimen@=\the\wdz@}%
 \kern\A@ \raise\B@\boxz@ \kern-\A@
 \tmp@ \divide\dimen@\tw@ \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \boxz@ }
\xydef@\filled@Rectangle@{\filled@Region@\filledRectangle@@}
\xydef@\filled@Oval@{\filled@Region@\filledOval@@}
\xydef@\filled@Circle@{\filled@Region@\filledCircle@@}
\xydef@\filled@Ellipse@{\filled@Region@\filledEllipse@@}
\xydefcsname@{shape [F...]}#1{\xyFN@\Fshape@#1:@}
\xylet@\whichframe@@=\empty
\xylet@\whichoptions@@=\empty
\xydef@\Fshape@#1:{\def\whichframe@@{{#1}}%
 \DN@{{}}\ifx\whichframe@@\next@ \def\whichframe@@{{-}}\fi
 \expandafter\DN@\expandafter{\the\Edge@c}\DNii@{\circleEdge}\ifx\next@\nextii@
 \DN@##1{\def\whichframe@@{[o]##1}}%
 \expandafter\next@\expandafter{\whichframe@@}\fi
 \let\whichoptions@@=\empty \xyFN@\Fshape@i}
\xydef@\Fshape@i{%
 \ifx @\next \let\next@=\Fshape@x
 \else\addLT@\ifx\next \let\next@=\Fshape@iii
 \else \let\next@=\Fshape@ii \fi\fi \next@}
\xydef@\Fshape@ii#1:{%
 \expandafter\def\expandafter\whichoptions@@\expandafter{\whichoptions@@[#1]}%
 \xyFN@\Fshape@i}
\xydef@\Fshape@iii#1:{\DN@##1{\def\whichframe@@{#1##1}}%
 \expandafter\next@\expandafter{\whichframe@@}\xyFN@\Fshape@i}
\xydef@\Fshape@x @{%
 \edef\next@##1{\noexpand\addbeforeDrop@@{{\EdgefromtheEdge@##1}}}%
 \DNii@##1##2{\next@{\setbox\z@=\object##2\frm##1\Drop@@}}%
 \expandafter\expandafter\expandafter\nextii@
 \expandafter\expandafter\expandafter{%
 \expandafter\whichframe@@\expandafter}\expandafter{\whichoptions@@}}
\xydef@\xycircleframe@x@{\L@=\R@ \xycircleframe@x@i}%
\xydef@\xyellipseframe@x@#1#2{\R@=#1\relax \L@=#2\relax \xycircleframe@x@i}
\xydef@\xycircleframe@x@i{%
 \ifx\framehfill\frm@solidh@@\def\circleSTYLE@{}%
 \else\ifx\framehfill\frm@doth@@
 \expandafter\def\expandafter\circleSTYLE@\expandafter{\addDOT@{}}%
 \else\ifx\framehfill\frm@dashh@@
 \expandafter\expandafter\expandafter\def\expandafter\expandafter
 \expandafter\circleSTYLE@\expandafter\expandafter\expandafter
 {\expandafter\addDASH@\addDASH@{}}%
 \fi\fi\fi \xycircleframe@x@x }
\xydef@\xycircleframe@x@x{\hbox{\vbox{\vskip\L@
 \hbox to2\R@{\hfill \buildcircle@ \hfill}\vskip\L@ }}}
\xydef@\UseCircleframes@{%
 \let\circled@x@=\xycircleframe@x@
 \let\ellipsed@x@=\xyellipseframe@x@
 \let\UseCircleframes@=\relax }
\xywithoption{curve}{\UseCircleframes@}%
\xydef@\UnloadFrames@{%
 \let\framed@body@@=\framed@body@
 \let\circled@x@@=\circled@x@
 \let\ellipsed@x@@=\ellipsed@x@
 \let\filledRectangle@@=\bblacked@
 \let\filledCircle@@=\bblacked@
 \let\filledEllipse@@=\bblacked@
 \let\filledOval@@=\bblacked@
 }
\xyaddunsupport{frame}\UnloadFrames@
\xyendinput

xygraph.tex
%% xygraph.tex from $Id: xygraph.doc,v 3.2 1995/09/19 18:22:27 kris Exp kris $
%%
%% Xy-pic ``Graph Combinator feature'' option.
%% Copyright (c) 1994-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined \input xy \fi
\xyprovide{graph}{Graph feature}{\stripRCS$Revision: 3.2 $}%
 {Kristoffer H.~Rose}{kris@diku.dk}%
 {Computer Science, University of Copenhagen, Universitetsparken~1,
 DK--2100 K{\o}benhavn~{\O}}
\xyrequire{arrow}\xycatcodes
\xydef@\xygraph#1{\relax\graph#1\endgraph}
\xydef@\graph{\if\inxy@ \DN@{\xy@@{\nter@{}}}%
 \else \DN@{\addGT@{\addLT@\xy 0ex,.8ex}\xy@\xy{\nter@\endxy}}\fi \next@
 \xy@\xygraph{\senter@ \idfromc@{?NODE}\spushc@
 \expandafter\let\expandafter\next@\csname Q@graphbase\endcsname
 \ifx\next@\relax \setbase@\z@\z@{3pc}\z@
 \else \expandafter\next@ \fi}%
 \GRAPH[]}
\xydef@\endgraph{\ignorespaces}
\xydef@\GRAPH{\xyFN@\GRAPH@}
\xydef@\GRAPH@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\GRAPH@}%
 \else\ifx :\next \DN@:{\xy@:{}\expandafter\GRAPHar@\GRAPHeveryarrow@@}%
 \else\addDASH@\ifx\next
 \addDASH@\DN@{\xy@-{}\expandafter\GRAPHar@\GRAPHeveryline@@}%
 \else\ifx (\next
 \DN@({\xy@({\spushid@{?NODE}\idfromc@{?NODE}}\xyFN@\GRAPH@}%
 \else\ifx ,\next
 \DN@,{\xy@,{\cfromid@{?NODE}}\xyFN@\GRAPH@}%
 \else\ifx )\next
 \DN@){\xy@){\cfromid@{?NODE}%
 \tests@\z@{\idfroms@{?NODE}\z@ \spop@}{\xyerror@{) without (}{}}}%
 \xyFN@\GRAPH@}%
 \else\ifx \endgraph\next \DN@{\xy@@{\tests@\z@\spop@\sleave@\leave@}}%
 \else\ifx \end\next \DN@{\xy@@{\tests@\z@\spop@\sleave@\leave@}}%
 \else\ifx ~\next
 \DN@~{\xy@@{\enter@\cfromthec@}\afterNODE{\leave@ \xyFN@\GRAPH@}!}%
 \else \DN@{\afterNODE{\xyFN@\GRAPH@}}%
 \fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xylet@\GRAPHsaved@PATHafterPOS=\PATHafterPOS
\xylet@\GRAPHsaved@afterar@@=\afterar@@
\xydef@\GRAPHar@{%
 \let\PATHafterPOS=\afterNODE \let\afterar@@=\GRAPHafterar@ \ar}
\xydef@\GRAPHafterar@{%
 \let\PATHafterPOS=\GRAPHsaved@PATHafterPOS
 \let\afterar@@=\GRAPHsaved@afterar@@
 \xy@@{\lastNODE@@}\xyFN@\GRAPH@}
\xylet@\afterNODE@@=\empty
\xydef@\afterNODE#1{\xy@@{\enter@\pfromthep@}%
 \DN@##1{\def\afterNODE@@{\xy@@\leave@ \def\afterNODE@@{##1}#1}}%
 \expandafter\next@\expandafter{\afterNODE@@}%
 \xyFN@\NODE@}
\xylet@\lastNODE@@=\relax
\xylet@\theMOVE@@=\relax
\xydef@\NODE@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\NODE@}%
 \else\ifx [\next \DN@[##1]{\xy@{[##1]}{}%
 \def\theMOVE@@{[##1]}\xyFN@\MOVE@##1]}%
 \else\ifx "\next \DN@ "##1"{%
 \xy@{"##1"}{\cfromid@{##1}}\def\theMOVE@@{"##1"}\xyFN@\NODE@i}%
 \else\ifx ?\next \DN@ ?{%
 \xy@?{\cfromid@{?NODE}}\def\theMOVE@@{?}\xyFN@\NODE@i}%
 \else\ifx !\next \def\theMOVE@@{[]}\let\next@=\NODE@i
 \else \testAND@\iffalse
 \DN@##1{\xy@{}{\pfromc@ \advance\X@c\X@xbase \advance\Y@c\Y@xbase
 \czeroEdge@}\jumpMOVE@ \xyFN@\NODE@i}%
 \else\ifx \\\next
 \DN@\\{\xy@\\{\pfromc@ \advance\X@c\X@xbase \advance\Y@c\Y@xbase
 \R@c=\X@ybase \U@c=\Y@ybase \intersect@
 \advance\X@c-\X@ybase \advance\Y@c-\Y@ybase
 \czeroEdge@}\def\theMOVE@@{\\}\xyFN@\NODE@i}%
 \else \xyerror@{Illegal <node>}{}%
 \fi\fi\fi\fi\fi\fi\fi \next@}
\xydef@\jumpMOVE@@{&}
\xydef@\jumpMOVE@{\let\theMOVE@@=\jumpMOVE@@}
\xydef@\testAND@{{\aftergroup\ifx 
 \addAND@\ifx\next\addFalse@\else\addTrue@\fi}}
\xydef@\addFalse@{\aftergroup\iffalse}
\xydef@\addTrue@{\aftergroup\iftrue}
\xydef@\MOVE@{\xy@@{\count@=\z@ \count@@=\z@}%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\MOVE@}%
 \else\ifcat A\noexpand\next \let\next@=\MOVE@letter
 \else \let\next@=\MOVE@x \fi\fi \next@}
\xydef@\MOVE@letter{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\MOVE@letter}%
 \else\ifx u\next \DN@ u{\xy@@{\advance\count@\@ne}\xyFN@\MOVE@letter}%
 \else\ifx d\next \DN@ d{\xy@@{\advance\count@\m@ne}\xyFN@\MOVE@letter}%
 \else\ifx l\next \DN@ l{\xy@@{\advance\count@@\m@ne}\xyFN@\MOVE@letter}%
 \else\ifx r\next \DN@ r{\xy@@{\advance\count@@\@ne}\xyFN@\MOVE@letter}%
 \else \let\next@=\MOVE@x \fi\fi\fi\fi\fi \next@}
\xydef@\MOVE@x{%
 \ifx ]\next \DN@ ]{\MOVE@hop \xyFN@\NODE@i}%
 \else\ifx (\next \DN@{\MOVE@hop \xyFN@\MOVE@place}%
 \else\ifx !\next \DN@{\MOVE@hop \xyFN@\MOVE@place}%
 \else\ifx /\next \DN@{\MOVE@hop \xyFN@\MOVE@place}%
 \else\addLT@\ifx\next \DN@{\MOVE@hop \xyFN@\MOVE@place}%
 \else\addGT@\ifx\next \DN@{\MOVE@hop \xyFN@\MOVE@place}%
 \else\addDASH@\ifx\next \addDASH@\DN@{\xyerror@{- not implemented yet}{}}%
 \else \xyerror@{illegal <move>: \codeof\theMOVE@@}{}\let\next@=\NODE@i
 \fi\fi\fi\fi\fi\fi\fi \next@}
\xydef@\MOVE@hop{\xy@@{\pfromc@ \czeroEdge@
 \edef\next@{\the\count@@,\the\count@ @}\expandafter\vfromcartesian@@\next@
 \advance\X@c-\X@origin \advance\Y@c-\Y@origin
 \advance\X@c\X@p \advance\Y@c\Y@p}}
\xydef@\MOVE@place{\xy@@\no@@ \afterPLACE{\xyFN@\MOVE@}}
\xydef@\NODE@i{\let\next@=\NODE@x
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\NODE@i}%
 \else\addEQ@\ifx \next
 \addEQ@\DN@"##1"{\xy@{="##1"}{\idfromc@{##1}}\xyFN@\NODE@i}%
 \else\ifx !\next \DN@!{\xyFN@\NODE@escape}%
 \else\ifx :\next 
 \else\addDASH@\ifx\next
 \else\ifx (\next
 \else\ifx ,\next
 \else\ifx )\next
 \else\ifx ~\next
 \else\ifx [\next
 \else\ifx "\next
 \else\ifx ?\next
 \else\ifx ^\next
 \else\ifx _\next
 \else\ifx |\next
 \else\addLQ@\ifx\next
 \else\addRQ@\ifx\next
 \else \testAND@ \iffalse
 \else\ifx \\\next
 \else\ifx \endgraph\next
 \else\ifx \end\next
 \else \let\next@=\NODE@it
 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xydef@\NODE@x{\xy@@{\edef\lastNODE@@{\cfromthec@}}\afterNODE@@}
\xydef@\NODE@it{\let\PATHlabelit@@=\NODEit@ \PATHit@}
\xydef@\NODEit@#1{%
 \DN@{#1}\ifx\next@\empty \DN@{\addPLUS@\NODEit@i}%
 \else \DN@{\NODEit@i{#1}}\fi \next@}
\xydef@\NODEit@i#1#2{\xy@{*#1{#2}}{\drop@{#1}{#2}\idfromc@{#2}}\xyFN@\NODE@i}
\xydef@\NODE@escape{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\NODE@escape}%
 \else\ifcat A\noexpand\next
 \DN@##1{\csname graph <escape> \string!##1\endcsname}%
 \else\ifcat !\noexpand\next
 \DN@##1{\csname graph <escape> \string!##1\endcsname}%
 \else\ifx \bgroup\next
 \DN@##1{\xy@{!{##1}}{}\POS##1\relax \xyFN@\NODE@i}%
 \else\ifx ~\next \let\next@=\graphsetup@
 \else \DN@{\xyerror@{Unknown graph <escape>}{}\xyFN@\NODE@i}%
 \fi\fi\fi\fi\fi \next@}
\xydefcsname@{graph <escape> !M}#1#{\NODE@matrix{#1}}
\xydef@\NODE@matrix#1#2{\xyerror@{matrix feature not loaded}{}\xyFN@\GRAPH@}
\xydef@\NODE@matrix@#1#2{\xy@{!M#1{#2}}{}%
 \def\everyentry@{\GRAPHeveryentry}%
 \xymatrix#1{#2}%
 \let\everyentry@=\empty \insertmatrixingraph@ \xyFN@\NODE@i}
\xydef@\GRAPHeveryentry{\def\:{\ar}\def\="##1"{\xy@@{\idfromc@{##1}}}}
\xywithoption{matrix}{\let\NODE@matrix=\NODE@matrix@}
\xydef@\insertmatrixingraph@{%
 \xy@@{\enter@{\cfromthec@ \pfromthep@}%
 \expandafter\let\expandafter\next@\csname Q@1,1\endcsname
 \ifx\next@\relax\else
 \next@ \swap@
 \expandafter\let\expandafter\next@\csname Q@1,2\endcsname
 \ifx\next@\relax\else \next@ \setbase@\X@p\Y@p\X@c\Y@c
 \expandafter\let\expandafter\next@\csname Q@2,1\endcsname
 \ifx\next@\relax\else
 \next@ \setbase@@{-\X@c}{-\Y@c}\fi\fi\fi
 \leave@}}
\xydefcsname@{graph <escape> !P}#1#{\NODE@poly{#1}}
\xydef@\NODE@poly#1#2{\xyerror@{poly(gon) feature not loaded}{}\xyFN@\GRAPH@}
\xydef@\NODE@poly@#1#2{\xy@{!P#1{#2}}{}\xypoly@#1{#2}\xyFN@\NODE@i}
\xywithoption{poly}{\let\NODE@poly=\NODE@poly@}
\xydefcsname@{graph <escape> !E}#1#{\NODE@arc{#1}}
\xydef@\NODE@arc#1#2{\xyerror@{(ellipse+)arc feature not loaded}{}%
 \xyFN@\GRAPH@}
\xydef@\NODE@arc@#1#2{\xy@{!E#1{#2}}{}\ellipse#1{#2}\xyFN@\NODE@i}
\xywithoption{arc}{\let\NODE@arc=\NODE@arc@}
\xylet@\GRAPHeveryarrow@@=\empty
{\xyuncatcodes \gdef\next{@{-}}}
\xylet@\GRAPHeveryline@@=\next
\xydef@\graphsetup@~{\xyFN@\graphsetup@i}
\xydef@\graphsetup@i{%
 \ifx :\next \DN@:##1{\def\GRAPHeveryarrow@@{##1}\xyFN@\NODE@i}%
 \else\addDASH@\ifx\next
 \addDASH@\DN@##1{\def\GRAPHeveryline@@{##1}\xyFN@\NODE@i}%
 \else\ifcat A\next \DN@##1##2{\newgraphescape{##1}{##2}\xyFN@\NODE@i}%
 \else \DN@{\xyerror@{illegal graph setup \codeof\next@}{}\xyFN@\NODE@i}%
 \fi\fi\fi \next@}
\xydef@\newgraphescape#1{%
 \xydefcsname@{graph <escape> !#1}{%
 \expandafter\let\expandafter\next\csname G!#1\endcsname
 \ifx\next\relax \xyerror@{Unknown <graph> !-escape}{}\fi
 \expandafter\xyFN@\expandafter\NODE@\next}%
 \xydefcsname@{G!#1}}
\xyendinput

xyidioms.tex
%% xyidioms.tex from $Id: xyidioms.doc,v 3.1 1995/09/05 20:31:32 kris Exp kris $
%%
%% Format-dependent idioms for Xy-pic.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyidiomsloaded\empty \message{not reloaded}\endinput \fi
\let\xyidiomsloaded=\empty
\xywarnifdefined\A@ \dimendef\A@=4
\xywarnifdefined\B@ \dimendef\B@=6
\xywarnifdefined\R@ \dimendef\R@=8
\ifx\undefined\AveryUNLIKELYc@ntr@lSEQUENCE@@\else
\errmessage{Xy-pic Error: \string\undefined\space defined.}\fi
\ifx\undefined\literal@ \def\literal@#1{#1}\fi
\ifx\undefined\eat@ \def\eat@#1{}\fi
\xydef@\xyFN@{\futurelet\next}
\ifx\undefined\DN@ \def\DN@{\def\next@}\fi
\ifx\undefined\DNii@ \def\DNii@{\def\nextii@}\fi
\ifx\undefined\setboxz@h\def\setboxz@h{\setbox\z@\hbox}\fi
\ifx\undefined\wdz@ \def\wdz@{\wd\z@}\fi
\ifx\undefined\boxz@ \def\boxz@{\box\z@}\fi
\ifx\undefined\W@ \def\W@{\immediate\write16 }\fi
\ifx\undefined\space@ \def\space@.{\futurelet\space@\relax}\space@. \fi
\ifx\undefined\notempty \def\notempty#1{T\if @#1@F\else T\fi}\fi
\xydef@\xysetup@dummy#1{\xyuncatcodes#1}
\xywarnifdefined\xysetup@@
\ifx\AtEndDocument\undefined
 \expandafter\ifx\csname amsppt.sty\endcsname\relax
 \let\xysetup@@=\xysetup@dummy
 \else
 \def\xysetup@@#1{%
 \expandafter\def\expandafter\topmatter\expandafter{\topmatter
 #1\xyuncatcodes}}\fi
\else
 \def\xysetup@@#1{\AtBeginDocument{#1\xyuncatcodes}}
\fi
\ifx\xysetup@@\xysetup@dummy\else
 \xysetup@@{\let\xysetup@@=\xysetup@dummy \xyuncatcodes}\fi
\xywarnifdefined\xyclosedown@@
\ifx\AtEndDocument\undefined \let\xyclosedown@@=\eat@
\else \def\xyclosedown@@#1{\AtEndDocument{#1}}\fi
\ifx\amstexloaded@\relax
\xylet@\toks@ii=\toks@@ \endinput \fi
\ifx\@tempcnta\undefined
\xynew@{count}\count@@
\xynew@{count}\count@@@
\else
\xylet@\count@@=\@tempcnta
\xylet@\count@@@=\@tempcntb
\fi
\ifx\undefined\toks@ii \toksdef\toks@ii=2 \fi
\endinput

xyline.tex
%% xyline.tex from $Id: xyline.doc,v 3.2 1995/09/19 18:21:41 ross Exp $
%%
%% Xy-pic ``Line Width'' extension.
%% Copyright (c) 1993-1995 Ross Moore <ross@mpce.mq.edu.au>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined \input xy \fi
\xyprovide{line}{Line styles extension}{\stripRCS$Revision: 3.2 $}%
 {Ross Moore}{ross@mpce.mq.edu.au}%
 {Mathematics Department, Macquarie University, NSW~2109, Australia}
\xydefcsname@{*stylechar@|@}#1{\xyFN@\xywidthchar@#1@@}%
\xydefcsname@{style [thinner]}{\xyshape@thinner@}
\xydefcsname@{style [thicker]}{\xyshape@thicker@}
\xynew@{dimen}\xylinethick@ \xylinethick@=\xydashw@
\xydef@\xyshape@thicker@{\xylinewidth@i{\multiply\xylinethick@\tw@}}
\xydef@\xyshape@thinner@{\xylinewidth@i{\divide\xylinethick@\tw@}}
\xydef@\xylinewidth@i#1{#1\edef\next@{\xylinethick@=\the\xylinethick@}%
 \expandafter\addtotoks@\expandafter{%
 \expandafter\xylinewidth@@\expandafter{\next@}}}
\xydef@\xywidthchar@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xywidthchar@}%
 \else\ifx @\next \DN@ @@{\checkXyStyle@}%
 \else\ifx (\next \DN@ (##1)##2@@{%
 \xylinewidth@i{\xylinethick@=##1\xydashw@}}%
 \else\addLT@\ifx \next \addGT@{\addLT@\DN@ ##1}##2@@{%
 \xylinewidth@i{\xylinethick@=##1\relax}}%
 \else\ifx *\next \DN@ *@@{\checkXyStyle@}%
 \else\addEQ@\ifx \next \addEQ@\DN@##1@@{\checkXyStyle@
 \addtotoks@{\xynamestyle@{##1}}}%
 \else\ifx C\next \DN@ C##1@@{\xysetlinecap@{##1}@}%
 \else\ifx J\next \DN@ J##1@@{\xysetlinejoin@{##1}@}%
 \else\ifx M\next \DN@ M(##1)@@{\xymiterlimit@{##1}@}%
 \else \DN@##1@@{\xylinewidth@i{\xylinethick@=##1\relax}}%
 \fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xydef@\xylinecap@{2}
\xydef@\xylinejoin@{2}
\xydef@\xylinemiter@{10}
\xydefcsname@{style [bevel]}{\xyshape@bevel@}
\xydefcsname@{style [roundjoin]}{\xyshape@rdjoin@}
\xydefcsname@{style [miter]}{\xyshape@miter@}
\xydefcsname@{style [butt]}{\xyshape@butt@}
\xydefcsname@{style [roundcap]}{\xyshape@rdcap@}
\xydefcsname@{style [projcap]}{\xyshape@projcap@}
\xydef@\xyshape@butt@{\xysetlinecap@@0}
\xydef@\xyshape@rdcap@{\xysetlinecap@@1}
\xydef@\xyshape@projcap@{\xysetlinecap@@2}
\xydef@\xyshape@miter@{\xysetlinejoin@@0}
\xydef@\xyshape@rdjoin@{\xysetlinejoin@@1}
\xydef@\xyshape@bevel@{\xysetlinejoin@@2}
\xydef@\xysetlinecap@#1@{\DN@ii{#1}\count@=#1\relax
 \expandafter\DN@\expandafter{\the\count@}%
 \ifx\next@\next@ii\else
 \xywarning@{ignoring extra tokens in line-cap: \next@}\fi
 \expandafter\xysetlinecap@@\expandafter{\next@}}
\xydef@\xysetlinejoin@#1@{\DN@ii{#1}\count@=#1\relax
 \expandafter\DN@\expandafter{\the\count@}%
 \ifx\next@\next@ii\else
 \xywarning@{ignoring extra tokens in line-join: \next@}\fi
 \expandafter\xysetlinejoin@@\expandafter{\next@}}
\xydef@\xysetmiterlimit@#1@{\DN@ii{#1}\dimen@=#1\p@\relax
 \edef\next@{\expandafter\removePT@\the\dimen@}%
 \ifx\next@\next@ii\else
 \xywarning@{ignoring extra tokens in miter-limit: \next@}\fi
 \expandafter\xysetmiterlimit@@\expandafter{\next@}}
\xydef@\xysetlinecap@@#1{\xy@linecap@i{\def\xylinecap@{#1}}}
\xydef@\xysetlinejoin@@#1{\xy@linejoin@i{\def\xylinejoin@{#1}}}
\xydef@\xysetmiterlimit@@#1{%
 \xy@linemiter@i{\def\xylinemiter@{#1}}}
\xydef@\xy@linecap@i#1{#1\addtotoks@{\xy@linecap@@{#1}}}
\xydef@\xy@linejoin@i#1{#1\addtotoks@{\xy@linejoin@{#1}}}
\xydef@\xy@linemiter@i#1{#1\addtotoks@{\xy@linemiter@{#1}}}
\xydef@\xy@linecap@#1{\checkXyStyle@ \edef\xyprevcap@@{\xylinecap@}%
 #1\let\prexylinecap@=\prexylinecap@@ \let\postxylinecap@=\postxylinecap@@
 \applyLIFOstyle@\prexylinecap@{\xylinecap@}%
 \postxylinecap@{\xyprevcap@@}}
\xydef@\prexylinecap@@{\let\prexylinecap@=\eat@ 
 \let\postxylinecap@=\postxylinecap@@ \outputxylinecap@ }
\xydef@\postxylinecap@@{\let\postxylinecap@=\eat@ 
 \let\prexylinecap@=\prexylinecap@@ \resetxylinecap@@ }
\xylet@\prexylinecap@=\prexylinecap@@
\xylet@\postxylinecap@=\postxylinecap@@
\xydef@\outputxylinecap@#1{\xycapSpecial@@{#1}}
\xydef@\resetxylinecap@#1{\resetxylinecap@i{#1}\outputxylinecap@{#1}}
\xydef@\resetxylinecap@i#1{\def\xylinecap@{#1}}
\xylet@\resetxylinecap@@=\resetxylinecap@
\xylet@\xycapSpecial@@=\eat@
\xydef@\xy@linejoin@#1{\checkXyStyle@
 \edef\xyprevjoin@@{\xylinejoin@}#1%
 \let\prexylinejoin@=\prexylinejoin@@
 \let\postxylinejoin@=\postxylinejoin@@
 \applyLIFOstyle@\prexylinejoin@{\xylinejoin@}%
 \postxylinecap@{\xyprevjoin@@}}
\xydef@\prexylinejoin@@{\let\prexylinejoin@=\eat@ 
 \let\postxylinejoin@=\postxylinejoin@@ \outputxylinejoin@ }
\xydef@\postxylinejoin@@{\let\postxylinejoin@=\eat@ 
 \let\prexylinejoin@=\prexylinejoin@@ \resetxylinejoin@@ }
\xylet@\prexylinejoin@=\prexylinejoin@@
\xylet@\postxylinejoin@=\postxylinejoin@@
\xydef@\outputxylinejoin@#1{\xyjoinSpecial@@{#1}}
\xydef@\resetxylinejoin@#1{\resetxylinejoin@i{#1}\outputxylinejoin@{#1}}
\xydef@\resetxylinejoin@i#1{\def\xylinejoin@{#1}}
\xylet@\resetxylinejoin@@=\resetxylinejoin@
\xylet@\xyjoinSpecial@@=\eat@
\xydef@\xy@linemiter@#1{\checkXyStyle@
 \edef\xyprevmiter@@{\xylinemiter@}#1%
 \let\prexylinemiter@=\prexylinemiter@@
 \let\postxylinemiter@=\postxylinemiter@@
 \applyLIFOstyle@\prexylinemiter@{\xylinemiter@}%
 \postxylinecap@{\xyprevmiter@@}}
\xydef@\prexylinemiter@@{\let\prexylinemiter@=\eat@ 
 \let\postxylinemiter@=\postxylinemiter@@ \outputxylinemiter@ }
\xydef@\postxylinemiter@@{\let\postxylinemiter@=\eat@ 
 \let\prexylinemiter@=\prexylinemiter@@ \resetxylinemiter@@ }
\xylet@\prexylinemiter@=\prexylinemiter@@
\xylet@\postxylinemiter@=\postxylinemiter@@
\xydef@\outputxylinemiter@#1{\xymiterSpecial@@{#1}}
\xydef@\resetxylinemiter@#1{\resetxylinemiter@i{#1}\outputxylinemiter@{#1}}
\xydef@\resetxylinemiter@i#1{\def\xylinemiter@{#1}}
\xylet@\resetxylinemiter@@=\resetxylinemiter@
\xylet@\xymiterSpecial@@=\eat@
\xydef@\xypolyline#1{\xypolyline@{#1}}
\xydef@\xypolyline@#1{\hbox\bgroup
 \enter@{\pfromthep@ \basefromthebase@ \cfromthec@}%
 \def\xyps@list{}\edef\smapp@@{\s@bot}%
 \smapxy@i{\enter@{\pfromthep@ \basefromthebase@ }%
 \edef\xyps@list{\expandafter\removePT@\the\X@c\space
 \expandafter\removePT@\the\Y@c\space \xyps@list}\leave@}%
 \leave@ \xy@polystyle@@{#1}\xydopoly@style\egroup
 \def\Drop@@{\boxz@}\def\Connect@@{\boxz@}}%
\xylet@\xypolyline@Special=\eat@
\xylet@\xypolyfill@Special=\eat@
\xylet@\xypolyeofill@Special=\eat@
\xylet@\xypolydot@Special=\eat@
\xylet@\xypolydash@Special=\eat@
\xydef@\UnloadpolySpecials@{%
 \let\xypolyline@Special=\eat@
 \let\xypolyfill@Special=\eat@
 \let\xypolyeofill@Special=\eat@
 \let\xypolydot@Special=\eat@
 \let\xypolydash@Special=\eat@
}
\xydef@\xy@polystyle@#1{%
 \let\poly@style@@=\xypolyline@Special
 \DNii@{#1}\ifx\nextii@\empty 
 \else\DN@{*}\ifx\next@\nextii@ \let\poly@style@@=\xypolyfill@Special
 \else\DN@{?}\ifx\next@\nextii@ \let\poly@style@@=\xypolyeofill@Special
 \else\expandafter\DN@\expandafter{\addDOT@{}}\ifx\next@\nextii@
 \let\poly@style@@=\xypolydot@Special
 \else\expandafter\DN@\expandafter{\addDASH@{}}\ifx\next@\nextii@
 \let\poly@style@@=\xypolydash@Special
 \else\DN@{{*}}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{*}}%
 \else \def\poly@style@@{\xypolystraight@{#1}}%
 \fi\fi\fi\fi\fi\fi }
\xydef@\xydopoly@style{\expandafter\poly@style@@\expandafter{\xyps@list}}
\xydef@\xynopolystyle@#1#2{\xyundefinedLine@{polyline}{{#1}}@@}
\xydef@\xypolynospec@#1{\DNii@{#1}%
 \ifx\nextii@\empty\def\poly@style@@{\xypolystraight@{-}}%
 \else\DN@{.}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{.}}%
 \else\DN@{-}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{--}}%
 \else\DN@{*}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{.}}%
 \else\DN@{?}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{.}}%
 \else\DN@{{*}}\ifx\next@\nextii@ \def\poly@style@@{\xypolystraight@{*}}%
 \else \def\poly@style@@{\xypolystraight@{#1}}%
 \fi\fi\fi\fi\fi\fi }
\xydef@\xypolystraight@#1#2{%
 \enter@{\pfromthep@ \basefromthebase@ \cfromthec@}%
 \edef\smapp@@{\s@bot}\csname S@1\endcsname\pfromc@\def\smapp@@{1}%
 \smapxy@i{\czeroEdge@\enter@{\pfromthec@}\connect@\dir{#1}\leave@}\leave@ }
\xylet@\xy@polystyle@@=\xypolynospec@
\xydef@\UninstallPolylines@{%
 \UnloadpolySpecials@
 \let\xy@polystyle@@=\xypolynospec@ }
\UninstallPolylines@
\xydef@\xyundefinedLine@#1#2@@{%
 \xywarning@{The #1 #2 effect is not implemented with the current driver.}}%
\xydef@\xynolinewidth@#1{%
 \xyundefinedLine@{linewidth}{\the\xylinethick@}@@}%
\xydef@\xynolinecap@#1{\xyundefinedLine@{linecap}{\xylinecap@}@@}%
\xydef@\xynolinejoin@#1{\xyundefinedLine@{linejoin}{\xylinejoin@}@@}%
\xydef@\xynolinemiter@#1{\xyundefinedLine@{miterlimit}{\xylinemiter@}@@}%
\xylet@\xylinewidth@@=\xynolinewidth@
\xylet@\xy@linecap@@=\xynolinecap@
\xylet@\xy@linejoin@@=\xynolinejoin@
\xylet@\xy@linemiter@@=\xynolinemiter@
\xydef@\UnloadLine@#1{%
 \ifx#1\relax\else\xyunload@{line width extension}\fi
 \let\resetxyline@@=\resetxyline@
 \let\resetxylinecap@@=\resetxylinecap@
 \let\resetxylinejoin@@=\resetxylinejoin@
 \let\resetxylinemiter@@=\resetxylinemiter@
 \let\transxyline@@=\DN@
 \let\xylineSpecial@@=\eat@
 \let\xycapSpecial@@=\eat@
 \let\xyjoinSpecial@@=\eat@
 \let\xymiterSpecial@@=\eat@
 \let\xylinewidth@@=\xynolinewidth@
 \let\xy@linecap@@=\xynolinecap@
 \let\xy@linejoin@@=\xynolinejoin@
 \let\xy@linemiter@@=\xynolinemiter@
 \UninstallPolylines@ }
\xyaddunsupport{line}{\UnloadLine@\relax}
\xydef@\xylinewidth@#1{\checkXyStyle@
 \edef\xyprevwidth@@{\the\xylinethick@}%
 #1\let\prexyline@=\prexyline@@ \let\postxyline@=\postxyline@@
 \applyLIFOstyle@\prexyline@{\the\xylinethick@}\postxyline@{\xyprevwidth@@}}
\xydef@\prexyline@@{\let\prexyline@=\eat@ 
 \let\postxyline@=\postxyline@@ \outputxyline@ }
\xydef@\postxyline@@{\let\postxyline@=\eat@ 
 \let\prexyline@=\prexyline@@ \resetxyline@@ }
\xylet@\prexyline@=\prexyline@@
\xylet@\postxyline@=\postxyline@@
\xydef@\resetxyline@#1{\resetxyline@i{#1}\outputxyline@{#1}}
\xydef@\resetxyline@i#1{}%
\xydef@\outputxyline@#1{\transxyline@@{#1}%
 \expandafter\xylineSpecial@@\expandafter{\next@}}
\xylet@\resetxyline@@=\resetxyline@
\xydef@\transxyline@#1{\edef\next@{\removePT@#1}}
\xylet@\transxyline@@=\DN@
\xylet@\xylineSpecial@@=\eat@
\xyendinput

xymatrix.tex
%% xymatrix.tex from $Id: xymatrix.doc,v 3.1 1995/09/05 20:31:32 kris Exp kris $
%%
%% Xy-pic ``Matrix'' feature.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined \input xy \fi
\xyprovide{matrix}{Matrix feature}{\stripRCS$Revision: 3.1 $}%
 {Kristoffer H.~Rose}{kris@diku.dk}%
 {Computer Science, University of Copenhagen, Universitetsparken~1,
 DK--2100 K{\o}benhavn~{\O}}
\xynew@{count}\Row
\xynew@{count}\Col
\xydef@\maxrow@{0}
\xydef@\maxcol@{0}
\xydef@\maxcolrow@{0}
\xynew@{toks}\queue@
\xynew@{toks}\queue@@
\xynew@{count}\qcount@
\xynew@{count}\qcount@@
\xydef@\clearq@{%
 \global\queue@={}\global\qcount@=\@ne
 \global\queue@@={}\global\qcount@@=\z@}
\xydef@\addq@#1{\global\advance\matrixsize@\@ne
 \ifnum\qcount@@<\qcount@ \let\addq@@=\addq@i
 \else \let\addq@@=\addq@ii \fi
 \expandafter\addq@@\the\queue@@\addq@@{#1}}
\xylet@\addq@@=\relax
\xydef@\addq@i#1\addq@@#2{%
 \global\advance\qcount@@\@ne \global\queue@@={#1#2}}
\xydef@\addq@ii#1\addq@@#2{%
 \global\advance\qcount@\@ne \global\qcount@@=\z@ 
 \global\queue@=\expandafter{\the\queue@#1#2}\global\queue@@={}}
\xydef@\finishq@{\expandafter\addq@ii\the\queue@@\addq@@{}}
\xynew@{count}\matrixsize@
\xydef@\xymatrixnocompile{%
 \message{<xymatrix}\global\matrixsize@=\z@
 \if\inxy@
 \DN@{\nter@{}\xy@\xymatrix{\enter@{%
 \def\noexpand\xy@minX@@{\xy@minX@@}\def\noexpand\xy@maxX@@{\xy@maxX@@}%
 \def\noexpand\xy@minY@@{\xy@minY@@}\def\noexpand\xy@maxY@@{\xy@maxY@@}%
 \edef\noexpand\xymatrixprefix@@{\codeof\xymatrixprefix@@}}}}%
 \else \DN@{\xy \nter@\endxy \xy@\xymatrix{\nter@{}}}\fi \next@
 \xy@@{\save@ \edef\matrixorigin@{\X@c=\the\X@c \Y@c=\the\Y@c}%
 \edef\xy@minX@@{\the\X@c}\edef\xy@maxX@@{\the\X@c}%
 \edef\xy@minY@@{\the\Y@c}\edef\xy@maxY@@{\the\Y@c}}%
 \xdef\maxrow@{0}\xdef\maxcol@{0}\xdef\maxcolrow@{0}%
 \mkHWdefaults@ \xymatrix@prefix""}
\xylet@\xymatrix=\xymatrixnocompile
\xydef@\xymatrixprefix@@{}
\xydef@\xymatrix@prefix"#1"{\DN@{#1}\edef\xymatrixprefix@@{\codeof\next@}%
 \DNii@##1{\xy@{"#1"}{\edef\xymatrixprefix@@{##1}}}%
 \expandafter\nextii@\expandafter{\xymatrixprefix@@}%
 \xyFN@\xymatrix@setup}
\xydef@\xymatrix@setup{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@setup}%
 \else\ifx \bgroup\next \let\next@=\xymatrix@ii
 \else\addAT@\ifx\next \addAT@\DN@{\xy@{@}{}\xyFN@\xymatrix@at}%
 \else\ifx "\next \let\next@=\xymatrix@prefix
 \else \DN@{\xyerror@{\string\xymatrix<setup>{<rows>} expected}{}}%
 \fi\fi\fi\fi \next@}
\xydef@\xymatrix@ii#1{\xymatrix@pretypeset{#1}%
 \ifnum\maxcol@=\z@ \mkWcol@ \mkWmax@
 \xdef\maxcol@{\the\Col}\xdef\maxcolrow@{\the\Row}\fi
 \message{\maxcol@ x\maxrow@}%
 \xymatrix@measureit@@
 \xymatrix@typeset{#1}\restore\xymatrix@insert
 \xy@@\leave@ \message{\the\matrixsize@>}\leave@\ignorespaces}
\xydef@\xymatrixcompile#1#{\xymatrixcompile@{#1}}
\xydef@\xymatrixcompile@#1#2{\xycompile{\xymatrixnocompile#1{#2}}}
\xydef@\CompileMatrices{\let\xymatrix=\xymatrixcompile}
\xydef@\NoCompileMatrices{\let\xymatrix=\xymatrixnocompile}
\xydef@\xy@cossign@@{+}
\xydef@\xy@sinsign@@{+}
\xydef@\xy@cosabs@@{1}
\xydef@\xy@sinabs@@{0}
\xydef@\xy@tanabs@@{0}
\xydef@\xy@cotabs@@{100}
\xydef@\xymatrix@rotation{%
 \xy@@{%
 \edef\xy@cossign@@{\ifdim\cosDirection\p@<\z@-\else+\fi}%
 \edef\xy@sinsign@@{\ifdim\sinDirection\p@<\z@-\else+\fi}%
 \edef\xy@cosabs@@{%
 \if\xy@cossign@@\cosDirection\else\xy@cossign@@\cosDirection\fi}%
 \edef\xy@sinabs@@{%
 \if\xy@sinsign@@\sinDirection\else\xy@sinsign@@\sinDirection\fi}%
 \dimen@=\xy@cosabs@@\p@ \dimen@ii=\xy@sinabs@@\p@
 \ifdim\dimen@ii<.01\p@ \def\xy@cotabs@@{100}%
 \else \quotient@\xy@cotabs@@\dimen@\dimen@ii \fi
 \dimen@=\xy@cosabs@@\p@ \dimen@ii=\xy@sinabs@@\p@
 \ifdim\dimen@<.01\p@ \def\xy@tanabs@@{100}%
 \else \quotient@\xy@tanabs@@\dimen@ii\dimen@ \fi}}
\xylet@\xymatrixsavedCOORD@=\relax
\xydef@\xymatrix@pretypeset#1{%
 \global\Row=\z@ \xdef\maxcol@{0}\clearq@
 \setbox8=\vtop{%
 \ifx\xymatrixsavedCOORD@\relax \let\xymatrixsavedCOORD@=\COORD@ \fi
 \let\COORD@=\xymatrixCOORD@
 \everycr{}\let\\=\cr \tabskip=\z@ \offinterlineskip
 \halign{\prentry@ ##!@&&\xyFN@\prentry@@##!@\cr#1\crcr}%
 \prentry@@@}%
 \xdef\maxrow@{\the\Row}%
 \finishq@}
\xydef@\prentry@{\relax
 \ifnum\Row>\z@
 \ifnum\maxcol@<\Col\xdef\maxcol@{\the\Col}\xdef\maxcolrow@{\the\Row}\fi
 \expandafter\xdef\csname maxcol@\the\Row\endcsname{\the\Col}\fi
 \global\advance\Row\@ne \global\Col=\z@ \xyFN@\prentry@@}
\xylet@\lastprentry@@=\relax
\xydef@\xyeatall@{\let\xy@=\xyeat@ \let\oxy@=\xyeat@ \let\xy@@ix@=\eat@}
\xydef@\prentry@@{\global\advance\Col\@ne
 \let\next@=\prentry@@norm
 \ifoldxymatrix@\else \ifx *\next \DN@*{\xyFN@\prentry@@star}\fi \fi
 \next@}
\xydef@\prentry@@star{\ifx *\next \DN@*{\xyFN@\prentry@@star@ii}%
 \else \DN@##1##{\prentry@@star@i{##1}}\fi \next@}
\xydef@\prentry@@star@i#1#2#3!@{\gdef\lastprentry@@{*#1{#2}#3}%
 \setbox\lastobjectbox@=\object#1{#2}%
 \prentry@@x}
\xydef@\prentry@@star@ii{%
 \ifx [\next
 \DN@[##1]{\DN@####1{\def\entrymodifiers@{[##1]####1}}%
 \expandafter\next@\expandafter{\entrymodifiers@}\prentry@@norm}%
 \else
 \DN@##1{\DN@####1{\def\entrymodifiers@{##1####1}}%
 \expandafter\next@\expandafter{\entrymodifiers@}\prentry@@norm}%
 \fi \next@}
\xydef@\prentry@@norm#1!@{\gdef\lastprentry@@{#1}%
 \DN@{\setbox\lastobjectbox@=\object}%
 \expandafter\next@\entrymodifiers@{\xyeatall@ \everyentry@ #1}%
 \prentry@@x}
\xydef@\prentry@@x{%
 \edef\next@{{\noexpand\pre@emit{\the\Row}{\Upness@}{\the\Col}{\Leftness@}%
 {\the\L@c}{\the\R@c}{\the\D@c}{\the\U@c}{\expandafter\noexpand\the\Edge@c}}}%
 \expandafter\addq@\next@ \box\lastobjectbox@}
\xynew@{if}\ifoldxymatrix@ \oldxymatrix@false
\xydef@\prentry@@@{\relax \let\next@=\prentry@@@i
 \ifoldxymatrix@ \ifnum\Col=\@ne \ifx\lastprentry@@\empty
 \global\advance\Row\m@ne \let\next@=\relax \fi\fi\fi
 \global\let\lastprentry@@=\relax \next@}
\xydef@\prentry@@@i{%
 \ifnum\maxcol@<\Col \xdef\maxcol@{\the\Col}\xdef\maxcolrow@{\the\Row}\fi
 \expandafter\xdef\csname maxcol@\the\Row\endcsname{\the\Col}}
\xydef@\xy@minX@@{\z@}
\xydef@\xy@maxX@@{\z@}
\xydef@\xy@minY@@{\z@}
\xydef@\xy@maxY@@{\z@}
\xydef@\pre@emit#1#2#3#4#5#6#7#8#9{%
 \global\Row=#1\global\Col=#3\relax
 \ifnum#3=\@ne
 \ifnum#1=\@ne \xy@@{\matrixorigin@}%
 \else \count@@=#1\advance\count@@\m@ne
 \edef\next@{\noexpand\xy@@{\noexpand\cfromid@
 {\xymatrixprefix@@\the\count@@,1}}}\next@
 \pre@emit@ \W@maxout\Hrow@c@@\W@maxin\Hrow@in\xy@tanabs@@
 \X@c\xy@sinsign@@\xy@sinabs@@\xymatrixrowsep@
 \pre@emit@ \Hrow@c@@\W@maxout\Hrow@in\W@maxin\xy@cotabs@@
 \Y@c{-\xy@cossign@@}\xy@cosabs@@\xymatrixrowsep@
 \fi
 \else \count@@=#3\advance\count@@\m@ne
 \pre@emit@ \Wcol@c@@\H@maxout\Wcol@in\H@maxin\xy@cotabs@@
 \X@c\xy@cossign@@\xy@cosabs@@\xymatrixcolsep@
 \pre@emit@ \H@maxout\Wcol@c@@\H@maxin\Wcol@in\xy@tanabs@@
 \Y@c\xy@sinsign@@\xy@sinabs@@\xymatrixcolsep@
 \fi
 \DN@##1{\xy@@{\L@c=#5\R@c=#6\D@c=#7\U@c=#8\Edge@c={#9}\idfromc@{##1#1,#3}}}%
 \expandafter\next@\expandafter{\xymatrixprefix@@}%
 \xy@@{%
 \dimen@=\X@c \advance\dimen@-\L@c
 \ifdim\dimen@<\xy@minX@@ \edef\xy@minX@@{\the\dimen@}\fi
 \dimen@=\X@c \advance\dimen@+\R@c
 \ifdim\dimen@>\xy@maxX@@ \edef\xy@maxX@@{\the\dimen@}\fi
 \dimen@=\Y@c \advance\dimen@-\D@c
 \ifdim\dimen@<\xy@minY@@ \edef\xy@minY@@{\the\dimen@}\fi
 \dimen@=\Y@c \advance\dimen@+\U@c
 \ifdim\dimen@>\xy@maxY@@ \edef\xy@maxY@@{\the\dimen@}\fi}}
\xydef@\pre@emit@#1#2#3#4{#1\A@ #2\B@ #3\R@ #4\dimen@
 \edef\next@{{\the\A@}{\the\B@}{\the\R@}{\the\dimen@}}%
 \expandafter\pre@emit@i\next@}
\xydef@\pre@emit@i#1#2#3#4#5{\xy@@{%
 \dimen@=#2\R@=#5\dimen@ \dimen@=#1\relax \ifdim\R@>\dimen@ \R@=\dimen@ \fi
 \dimen@=#4\B@=#5\dimen@ \dimen@=#3\relax \ifdim\B@>\dimen@ \B@=\dimen@ \fi
 \advance\R@\B@}%
 \pre@emit@ii}
\xydef@\pre@emit@ii#1#2#3#4{\xy@@{%
 \dimen@=#4\dimen@=#3\dimen@ \advance\R@\dimen@ \advance#1#2\R@}}
\xydef@\Wcol@in#1{#1=\csname Wcol@\the\Col\endcsname #1=.5#1}
\xydef@\Wcol@out#1{#1=\csname Wcol@\the\Col\endcsname #1=.5#1}
\xydef@\Wcol@c@@#1{#1=\csname Wcol@\the\count@@\endcsname #1=.5#1}
\xydef@\W@maxin#1{#1=\W@max #1=.5#1}
\xydef@\W@maxout#1{#1=\W@max #1=.5#1}
\xydef@\Hrow@in#1{#1=\csname Hrow@\the\Row\endcsname #1=.5#1}
\xydef@\Hrow@out#1{#1=\csname Hrow@\the\Row\endcsname #1=.5#1}
\xydef@\Hrow@c@@#1{#1=\csname Hrow@\the\count@@\endcsname #1=.5#1}
\xydef@\H@maxin#1{#1=\H@max #1=.5#1}
\xydef@\H@maxout#1{#1=\H@max #1=.5#1}
\xydef@\H@max{\z@}
\xydef@\W@max{\z@}
\xydef@\HW@max{\z@}
\xydef@\mkHrow@{}
\xydef@\mkWcol@{}
\xydef@\mkHmax@{}
\xydef@\mkWmax@{}
\xydef@\mkHWdefaults@{%
 \let\mkHrow@=\Hrow@R \let\mkWcol@=\Wcol@C
 \def\mkHmax@{\ifdim\dimen@>\H@max\relax \xdef\H@max{\the\dimen@}\fi}%
 \def\mkWmax@{\ifdim\dimen@>\W@max\relax \xdef\W@max{\the\dimen@}\fi}}
\xydef@\Hrow@R{\expandafter\xdef\csname Hrow@\the\Row\endcsname{\the\dimen@}}
\xydef@\Wcol@C{\expandafter\xdef\csname Wcol@\the\Col\endcsname{\the\dimen@}}
\xydef@\Hrow@max{\expandafter\gdef\csname Hrow@\the\Row\endcsname{\H@max}}
\xydef@\Wcol@max{\expandafter\gdef\csname Wcol@\the\Col\endcsname{\W@max}}
\xydef@\xymatrix@measureit{%
 \xdef\H@max{\z@}\xdef\W@max{\z@}%
 \setbox6=\vbox{\unvbox8 \global\Row=\maxrow@
 \loop@ \dimen@ii=\lastskip\unskip \ifnum\z@<\Row
 \setbox4=\lastbox \dimen@=\dp4 \advance\dimen@\ht4 \mkHrow@ \mkHmax@
 \ifnum\Row=\maxcolrow@
 \setbox2=\hbox{\unhbox4
 \global\Col=\maxcol@
 \loop@ \dimen@ii=\lastskip\unskip \ifnum\z@<\Col
 \setbox\z@=\lastbox \dimen@=\wdz@ \mkWcol@ \mkWmax@
 \global\advance\Col\m@ne
 \repeat@}\fi
 \global\advance\Row\m@ne
 \repeat@}%
 \ifdim\H@max>\W@max \global\let\HW@max=\H@max
 \else \global\let\HW@max=\W@max \fi
 \the\queue@ \global\queue@={}}
\xylet@\xymatrix@measureit@@=\xymatrix@measureit
\xydef@\xymatrix@typeset#1{%
 \clearq@
 \hbox{\vtop{\xyqall@
 \xy@@{\ifx\xymatrixsavedCOORD@\relax
 \enter@{\noexpand\let\noexpand\COORD@\noexpand\xymatrixsavedCOORD@}%
 \let\xymatrixsavedCOORD@=\COORD@ \let\COORD@=\xymatrixCOORD@
 \else \enter@{}\fi}%
 \ifx\xymatrixsavedCOORD@\relax \let\xymatrixsavedCOORD@=\COORD@ \fi
 \let\COORD@=\xymatrixCOORD@
 \kern\z@ \global\Row=\z@
 \everycr{}\let\\=\cr \tabskip=\z@ \offinterlineskip
 \halign{\entry@##!@&&\entry@@##!@\cr#1\crcr}%
 \xy@@{\leave@}}}%
 \finishq@ \expandafter\xy@@\expandafter{\the\queue@}\global\queue@={}}
\xydef@\entry@{\relax \global\advance\Row\@ne \global\Col=\z@ \entry@@}
\xydef@\entry@@{\global\advance\Col\@ne
 \DN@##1,##2,##3@{\xy@{ENTRY "##3##1,##2"}{\Row=##1 \Col=##2\relax
 \cfromid@{##3##1,##2}\pfromc@}}%
 \edef\nextii@{\the\Row,\the\Col,\xymatrixprefix@@ @}%
 \expandafter\next@\nextii@
 \xyFN@\entry@@i}
\xydef@\entry@@i{\let\next@=\entry@@norm
 \ifoldxymatrix@\else \ifx *\next \DN@*{\xyFN@\entry@@star}\fi \fi
 \next@}
\xydef@\entry@@star{\ifx *\next \DN@*{\xyFN@\entry@@star@ii}%
 \else \DN@##1##{\entry@@star@i{##1}}\fi \next@}
\xydef@\entry@@star@i#1#2#3!@{%
 \xy@@ix@{{#1}{#2}}\xy@@{\expandafter\dropentry@\the\toks9}%
 \setboxz@h{\xyqall@
 \ifx\xymatrixsavedCOORD@\relax \let\xymatrixsavedCOORD@=\COORD@ \fi
 \let\COORD@=\xymatrixCOORD@ \everyentry@ #3}%
 \setbox\z@=\copy\voidb@x}
\xydef@\entry@@star@ii{%
 \ifx [\next
 \DN@[##1]{\DN@####1{\def\entrymodifiers@{[##1]####1}}%
 \expandafter\next@\expandafter{\entrymodifiers@}\entry@@norm}%
 \else
 \DN@##1{\DN@####1{\def\entrymodifiers@{##1####1}}%
 \expandafter\next@\expandafter{\entrymodifiers@}\entry@@norm}%
 \fi \next@}
\xydef@\entry@@norm#1!@{%
 \DN@##1{\expandafter\xy@@ix@
 \expandafter{\expandafter{\entrymodifiers@}{##1}}}%
 \expandafter\next@\expandafter{\everyentry@#1}%
 \xy@@{\expandafter\dropentry@\the\toks9}%
 \setbox\z@=\expandafter\object\entrymodifiers@{\xyqall@
 \ifx\xymatrixsavedCOORD@\relax \let\xymatrixsavedCOORD@=\COORD@ \fi
 \let\COORD@=\xymatrixCOORD@ \everyentry@ #1}%
 \setbox\z@=\copy\voidb@x}
\xydef@\dropentry@#1#2{\drop@{#1}{\xyeatall@
 \ifx\xymatrixsavedCOORD@\relax \let\xymatrixsavedCOORD@=\COORD@ \fi
 \let\COORD@=\xymatrixCOORD@ #2}}
\xydef@\xyqall@{%
 \ifxysaving@ \let\xy@=\xyqs@ \let\xy@@ix@=\xysave@@toksix@
 \else \let\xy@=\xyq@ \let\xy@@ix@=\xyq@@toksix@ \fi
 \let\oxy@=\xy@}
\xydef@\xyq@#1#2{\addq@{#2}}
\xydef@\xyq@@toksix@{\begingroup
 \xyuncatcodes \afterassignment\xyq@@toksix@i \global\toks9=}
\xydef@\xyq@@toksix@i{%
 \DN@##1{\endgroup \xy@@{\global\toks9={##1}}}%
 \expandafter\next@\expandafter{\the\toks9}}
\xydef@\xyqs@{\global\advance\matrixsize@\@ne \xysave@}
\xydef@\xymatrix@insert{%
 \xy@@{\edef\nextii@{{\xy@minX@@}{\xy@maxX@@}{\xy@minY@@}{\xy@maxY@@}}%
 \expandafter\xymatrix@insert@\nextii@}}
\xydef@\xymatrix@insert@#1#2#3#4{\matrixorigin@
 \L@c=+\X@c \advance\L@c-#1\relax
 \R@c=-\X@c \advance\R@c+#2\relax
 \D@c=+\Y@c \advance\D@c-#3\relax
 \U@c=-\Y@c \advance\U@c+#4\relax
 \Edge@c={\rectangleEdge}}
\xylet@\thematrixCOORD@@=\relax
\xylet@\thematrixprefix@@=\relax
\xydef@\xymatrixCOORD@{%
 \ifx [\next
 \DN@[##1]{\xy@{[##1]}{\def\thematrixCOORD@@{[##1]}}%
 \xyFN@\xymatrixCOORD@i##1]}%
 \else \let\next@=\xymatrixsavedCOORD@ \fi \next@}
\xydef@\xymatrixCOORD@i{\count@=\Row \count@@=\Col
 \let\thematrixprefix@@=\xymatrixprefix@@
 \ifcat A\noexpand\next
 \DN@##1{\expandafter\notrelaxorelse@\csname xymatrixCOORD@i@##1\endcsname
 \xymatrixCOORD@other}%
 \else\ifx ]\next \DN@]{\xymatrixCOORD@x}%
 \else\ifx "\next \DN@"##1"{\DN@{##1}\edef\thematrixprefix@@{\codeof\next@}%
 \xyFN@\xymatrixCOORD@ii}%
 \else \let\next@=\xymatrixCOORD@other \fi\fi\fi \next@}
\xydef@\xymatrixCOORD@i@u{\advance\count@ \m@ne\xyFN@\xymatrixCOORD@ii}
\xydef@\xymatrixCOORD@i@d{\advance\count@ \@ne \xyFN@\xymatrixCOORD@ii}
\xydef@\xymatrixCOORD@i@l{\advance\count@@\m@ne\xyFN@\xymatrixCOORD@ii}
\xydef@\xymatrixCOORD@i@r{\advance\count@@\@ne \xyFN@\xymatrixCOORD@ii}
\xydef@\xymatrixCOORD@ii{%
 \ifcat A\noexpand\next
 \DN@##1{\expandafter\notrelaxorelse@\csname xymatrixCOORD@i@##1\endcsname
 \xymatrixCOORD@error}%
 \else\ifx ]\next \DN@]{\xymatrixCOORD@x}%
 \else \let\next@=\xymatrixCOORD@xx \fi\fi \next@}
\xydef@\xymatrixCOORD@error#1{\DN@{#1}%
 \xyerror@{illegal <coord> (\codeof\next@): illegal [...] target form}{}%
 \xyFN@\xymatrixCOORD@ii}
\xydef@\xymatrixCOORD@other#1,#2]{%
 \advance\count@#1\advance\count@@#2\xymatrixCOORD@x}
\xydef@\xymatrixCOORD@x{%
 \DN@##1{\xy@@{%
 \expandafter\let\expandafter\next@\csname Q@##1\endcsname
 \ifx\next@\relax \xyerror@RC{##1}\else \next@ \fi}%
 \afterCOORD@}%
 \edef\nextii@{{\thematrixprefix@@\the\count@,\the\count@@}}%
 \expandafter\next@\nextii@}
\xydef@\xymatrixCOORD@xx{%
 \DN@##1{\xy@@{%
 \expandafter\let\expandafter\next@\csname Q@##1\endcsname
 \ifx\next@\relax \xyerror@RC{##1}\else \next@\no@@ \fi}%
 \afterPLACE\xymatrixCOORD@after}%
 \edef\nextii@{{\thematrixprefix@@\the\count@,\the\count@@}}%
 \expandafter\next@\nextii@}
\xydef@\xymatrixCOORD@after{%
 \ifx ]\next \DN@]{\afterCOORD@}%
 \else \let\next@=\xymatrixCOORD@error \fi \next@}
\xydef@\xyerror@RC#1{\xyerror@{in entry \string"\the\Row,\the\Col\string":
 No \codeof\thematrixCOORD@@\space(is \string"#1\string") from here}{}}
\xylet@\xymatrix@addop@@=\relax
\xydef@\xymatrix@at{\def\xymatrix@addop@@{\xymatrix@R\xymatrix@C}%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@at}%
 \else\ifx !\next \DN@!{\xyFN@\xymatrix@fix}%
 \else\addPLUS@\ifx \next \let\next@=\xymatrix@addop
 \else\addDASH@\ifx \next \let\next@=\xymatrix@addop
 \else\addEQ@\ifx \next \let\next@=\xymatrix@addop
 \else\ifx R\next \def\xymatrix@addop@@{\xymatrix@R}\DN@ R{\xymatrix@addop}%
 \else\ifx C\next \def\xymatrix@addop@@{\xymatrix@C}\DN@ C{\xymatrix@addop}%
 \else\ifx *\next \DN@*{\xyFN@\xymatrix@mods}%
 \else\ifx 1\next \DN@1{\def\everyentry@{\vphantom(}\xyFN@\xymatrix@setup}%
 \else \DN@{\afterDIRECTIONorEMPTY
 {\xymatrix@rotation \xyFN@\xymatrix@setup}{\xyFN@\xymatrix@setup}}%
 \fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
\xydef@\xymatrix@fix{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@fix}%
 \else\ifx R\next \let\mkHrow@=\Hrow@max \DN@ R{\xyFN@\xymatrix@setup}%
 \else\ifx C\next \let\mkWcol@=\Wcol@max \DN@ C{\xyFN@\xymatrix@setup}%
 \else \let\mkHrow@=\Hrow@max \let\mkWcol@=\Wcol@max
 \let\H@max=\HW@max \let\W@max=\HW@max
 \let\next@=\xymatrix@setup
 \fi\fi\fi \next@}
\xydef@\xymatrix@addop{\afterADDOP{\xyFN@\xymatrix@addop@}}
\xydef@\xymatrix@addop@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@addop@}%
 \else\ifx R\next \DN@ R{\xy@{R}{}\dimen@ii=\xymatrixrowsep@\xymatrix@addop@x}%
 \else\ifx C\next \DN@ C{\xy@{C}{}\dimen@ii=\xymatrixcolsep@\xymatrix@addop@x}%
 \else \DN@{\afterassignment\xymatrix@addop@x\dimen@ii=}\fi\fi\fi \next@}
\xydef@\xymatrix@addop@x{\expandafter\xy@\expandafter{\the\dimen@ii}{}%
 \xymatrix@addop@@ \xyFN@\xymatrix@setup}
\xydef@\xymatrix@R{\Addop@@\xymatrixrowsep@\dimen@ii}
\xydef@\xymatrix@C{\Addop@@\xymatrixcolsep@\dimen@ii}
\xydef@\xymatrixrowsep@{2pc}
\xydef@\xymatrixcolsep@{2pc}
\xydef@\xymatrixrowsep{\afterADDOP{\Addop@@\xymatrixrowsep@}}
\xydef@\xymatrixcolsep{\afterADDOP{\Addop@@\xymatrixcolsep@}}
\xydef@\xymatrix@mods{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@mods}%
 \else\ifx [\next
 \DN@ [##1]{\xy@{[##1]}{}\DN@####1{\def\entrymodifiers@{[##1]####1}}%
 \expandafter\next@\expandafter{\entrymodifiers@}\xyFN@\xymatrix@setup}%
 \else\addPLUS@\ifx \next \DN@##1{\DNii@{##1}\xyFN@\xymatrix@change}%
 \else\addDASH@\ifx \next \DN@##1{\DNii@{##1}\xyFN@\xymatrix@change}%
 \else\addEQ@\ifx \next \DN@##1{\DNii@{##1}\xymatrix@set}%
 \else \let\next@=\xymatrix@mods@error \fi\fi\fi\fi\fi \next@}
\xydef@\xymatrix@set{\begingroup \plainxy@
 \afterVECTORorEMPTY\xymatrix@mods@x\xymatrix@mods@error}
\xydef@\xymatrix@change{%
 \addEQ@\ifx\next \DN@##1{\expandafter\DNii@\expandafter{\nextii@##1}%
 \expandafter\xy@\expandafter{\nextii@}{}\begingroup \plainxy@
 \afterVECTORorEMPTY\xymatrix@mods@x\xymatrix@mods@xx}%
 \else \DN@{\expandafter\xy@\expandafter{\nextii@}{}\begingroup \plainxy@
 \afterVECTORorEMPTY\xymatrix@mods@x\xymatrix@mods@xx}\fi
 \next@}
\xydef@\xymatrix@mods@x{\expandafter\xy@\expandafter{\nextii@}{}%
 \def\next@##1##2##3{\def\nextii@####1{##1##2####1##3}}%
 \addGT@{\addLT@{\expandafter\next@\expandafter{\nextii@}}}%
 \DN@##1{\gdef\tmp@@@{{##1}}}%
 \edef\nextiii@{{\the\X@c,\the\Y@c}}%
 \expandafter\expandafter\expandafter\next@
 \expandafter\expandafter\expandafter{\expandafter\nextii@\nextiii@}%
 \endgroup
 \DN@##1{\xy@{##1}{}\DN@####1{\def\entrymodifiers@{##1####1}}%
 \expandafter\next@\expandafter{\entrymodifiers@}\xyFN@\xymatrix@setup}%
 \expandafter\next@\tmp@@@}
\xydef@\xymatrix@mods@xx{\expandafter\xy@\expandafter{\nextii@}{}%
 \expandafter\gdef\expandafter\tmp@@@\expandafter{\expandafter{\nextii@}}%
 \endgroup
 \DN@##1{\xy@{##1}{}\DN@####1{\def\entrymodifiers@{##1####1}}%
 \expandafter\next@\expandafter{\entrymodifiers@}\xyFN@\xymatrix@setup}%
 \expandafter\next@\tmp@@@}
\xydef@\xymatrix@mods@error{\endgroup
 \xyerror@{Impossible @*<addop><size> <setup>.}{}\xyFN@\xymatrix@setup}
\xywarnifdefined\entrymodifiers
\expandafter\def\addEQ@\entrymodifiers#1{\def\entrymodifiers@{#1}\ignorespaces}
\xydef@\entrymodifiers@{\entrybox}
\xydef@\entrybox#1{\hbox{\setbox\z@=\objectbox{#1}%
 \L@p=\wdz@ \D@p=\ht\z@ \advance\D@p\dp\z@
 \dimen@=\objectwidth@ \advance\dimen@-\L@p
 \ifdim\dimen@>\z@ \advance\L@p\dimen@ \R@p=.5\dimen@ \else \R@p=\z@ \fi
 \dimen@=\objectheight@ \advance\dimen@-\D@p
 \ifdim\dimen@>\z@ \advance\D@p\dimen@ \fi
 \dimen@=\objectmargin@ \advance\L@p2\dimen@ \advance\D@p2\dimen@ 
 \U@p=-.5\ht\z@ \advance\U@p.5\dp\z@ \advance\R@p\objectmargin@
 \setboxz@h{\kern\R@p \raise\U@p\boxz@}%
 \wdz@=\L@p \ht\z@=.5\D@p \dp\z@=.5\D@p \boxz@}}
\xywarnifdefined\everyentry
\expandafter\def\addEQ@\everyentry#1{\def\everyentry@{#1}\ignorespaces}
\xylet@\everyentry@=\empty
\xyendinput

xyrecat.tex
%% xyrecat.tex from $Id: xyrecat.doc,v 3.1 1995/09/05 20:31:32 kris Exp $
%%
%% Xy-pic ``Reset Category Codes'' utility.
%% Copyright (c) 1994-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\xyuncatcodes
\xyrecat @ 64 \catcode 64 11
\xymakeADD@\addHASH@ # 35
\xymakeADD@\addDOLL@ $ 36
\xymakeADD@\addAND@ & 38
\xymakeADD@\addRQ@ ' 39
\xymakeADD@\addPLUS@ + 43
\xymakeADD@\addDASH@ - 45
\xymakeADD@\addDOT@ . 46
\xymakeADD@\addLT@ < 60
\xymakeADD@\addEQ@ = 61
\xymakeADD@\addGT@ > 62
\xymakeADD@\addLQ@ ` 96
\endinput

xyrotate.tex
%% xyrotate.tex from $Id: xyrotate.doc,v 3.2 1995/09/19 18:21:41 ross Exp $
%%
%% Xy-pic ``Rotate and Scale extension'' option.
%% Copyright (c) 1993-1995 Ross Moore <ross@mpce.mq.edu.au>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% See the companion README and INSTALL files for further information.
%% Copyright (c) 1991-1995 Kristoffer H. Rose <kris@diku.dk>
%%
%% The Xy-pic package is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by the
%% Free Software Foundation; either version 2 of the License, or (at your
%% option) any later version.
%%
%% The Xy-pic package is distributed in the hope that it will be useful, but
%% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
%% or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
%% for more details.
%%
%% You should have received a copy of the GNU General Public License along
%% with this package; if not, write to the Free Software Foundation, Inc.,
%% 675 Mass Ave, Cambridge, MA 02139, USA.
%%
\ifx\xyloaded\undefined \input xy \fi
\xyprovide{rotate}{Rotate and Scale extension}{\stripRCS$Revision: 3.2 $}%
 {Ross Moore}{ross@mpce.mq.edu.au}%
 {Mathematics Department, Macquarie University, NSW~2109, Australia}
\xydef@\xyundefinedRotate@#1#2@@{%
 \xywarning@{The #1 #2 effect is not implemented with the current driver.}}%
\xydef@\NoResizing{\xyNoResizing@}
\xydef@\UseResizing{\xyUseResizing@}
\xydef@\xyNoResizing@{%
 \global\let\origxyrescale@=\xyrescale@
 \global\let\origxyrotSizeMod@=\xyrotateSizeMod@
 \global\let\xyNoResizing@=\xyNoResizing@@
 \global\let\xyUseResizing@=\xyUseResizing@@
 \xyNoResizing@@ }
\xydef@\xyNoResizing@@{%
 \global\let\xyrescale@=\xyignorescale@
 \global\let\xyrotateSizeMod@=\xyignoreSizeMod@
 }
\xylet@\xyUseResizing@=\relax
\xydef@\xyUseResizing@@{%
 \global\let\xyrescale@=\origxyrescale@
 \global\let\xyrotateSizeMod@=\origxyrotSizeMod@
 }
\xydefcsname@{shape [@...]}#1{\xyrotatechar@#1@@}%
\xydefcsname@{shape [<...]}#1{\xyshearchar@{#1}@@}%
\xydefcsname@{shape [*...]}#1{\xyscalechar@{#1}@@}%
\xydefcsname@{shape [left]}{\xyshape@left@}
\xydefcsname@{shape [right]}{\xyshape@right@}
\xydefcsname@{shape [flip]}{\xyshape@flip@}
\xydefcsname@{shape [halfsize]}{\xyshape@halfsize@}
\xydefcsname@{shape [dblsize]}{\xyshape@dblsize@}
\xydefcsname@{shape [vflip]}{\xyshape@vflip@}
\xydefcsname@{shape [hflip]}{\xyshape@hflip@}
\xydef@\preXYtransform@{}
\xydef@\postXYtransform@{}
\xywarnifdefined\preXYtransform@@
\xywarnifdefined\postXYtransform@@
 \gdef\preXYtransform@@{}
 \gdef\postXYtransform@@{}
\xydef@\xy@transform@{}
\xydef@\preShape@@{}
\xydef@\postShape@@{}
\xydef@\modXYtransform@{%
 \ifx\xy@transform@\empty
 \transformDrop@\transformConnect@\resetTransform@\fi
 \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}%
 \expandafter\next@\expandafter{\preShape@@}%
 \DN@##1{\expandafter\gdef\expandafter\preXYtransform@@\expandafter{%
 \tmp@ ##1}}\expandafter\next@\expandafter{\preXYtransform@@}%
 \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}%
 \expandafter\next@\expandafter{\postShape@@}%
 \DN@##1{\expandafter\gdef\expandafter\postXYtransform@@\expandafter{%
 \postXYtransform@@ ##1}}\expandafter\next@\expandafter{\tmp@}}%
\xydef@\transformDrop@{\let\xy@transform@=\relax
 \expandafter\def\expandafter\Drop@@\expandafter{%
 \expandafter\preXYtransform@\Drop@@\postXYtransform@}}
\xydef@\transformConnect@{\let\xy@transform@=\relax
 \expandafter\def\expandafter\Connect@@\expandafter{%
 \expandafter\preXYtransform@\Connect@@\postXYtransform@}}
\xydef@\resetTransform@{\gdef\preXYtransform@@{}\gdef\postXYtransform@@{}}
\xydef@\xynametransform@#1{%
 \DN@{\expandafter\gdef\expandafter#1\expandafter{\the\toks@}}\next@ }
\xydef@\xyscalechar@#1@@{\xyscalechars@#1,#1,@@}
\xydef@\xyscalechars@#1,#2,#3@@{%
 \DN@{\xyrescale@(#1,#2)}%
 \dimen@=#1\p@
 \ifdim\dimen@>\z@ \else \ifdim\dimen@<\z@ \else
 \DN@{\xywarning@{invalid scaling factors #1, #2}}%
 \fi\fi \dimen@=#2\p@
 \ifdim\dimen@>\z@ \else \ifdim\dimen@<\z@ \else
 \DN@{\xywarning@{invalid scaling factors #1, #2 }}%
 \fi\fi \next@ }
\xydef@\xyrescale@(#1,#2){%
 \setboxz@h{\xyscale@@{#1}{#2}%
 \dimen@=\ifx-#1\R@c\advance\dimen@-\R@c \dimen@=-\dimen@
 \else#1\L@c \advance\dimen@-\L@c\fi
 \kern\dimen@\boxz@\kern-\dimen@}%
 \R@c=\if-#1\L@c\else#1\R@c\fi
 \L@c=\if-#1\R@c\else#1\L@c\fi
 \U@c=\if-#2\D@c\else#2\U@c\fi
 \D@c=\if-#2\U@c\else#2\D@c\fi }
\xydef@\xyignorescale@(#1,#2){\xywarning@{Ignoring rescale: #1,#2}%
 \setboxz@h{\xyscale@@{#1}{#2}\boxz@}}%
\xydef@\xyshape@halfsize@{\xyrescale@(.5,.5)}
\xydef@\xyshape@dblsize@{\xyrescale@(2,2)}
\xydef@\xyshape@flip@{\xyrescale@(-1,-1)}
\xydef@\xyshape@vflip@{\xyrescale@(1,-1)}
\xydef@\xyshape@hflip@{\xyrescale@(-1,1)}
\xydef@\xyrotatechar@{\bgroup
 \afterDIRECTIONorEMPTY{\xyrotateSizeMod@}{\xyFN@\xySpecialRotate@i}}
\xydef@\xySpecialRotate@i{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xySpecialRotate@i}%
 \else\ifx @\next \let\next@=\xyrotateSizeMod@
 \else\addEQ@\ifx \next
 \addEQ@\DN@##1@@{%
 \expandafter\xynametransform@\csname shape [##1]\endcsname\egroup}%
 \else\ifx !\next \DN@!{\egroup\getSpecialRotate@}%
 \else\ifx *\next \DN@*@@{\egroup\transformDrop@}%
 \else \DN@{\xySpecialRotate@@}%
 \fi\fi\fi\fi\fi \next@ }
\xydef@\getSpecialRotate@{\doSpecialRotate@@}
\xydef@\xyRotate@#1{\xyundefinedRotate@{rotate}{#1}@@}
\xydef@\xySpecialRotate@#1@@{\xyundefinedRotate@{rotate}{#1}@@\egroup}
\xydef@\doSpecialRotate@#1@@{\xyundefinedRotate@{special rotate}{#1}@@}
\xydef@\xyscale@#1#2{\xyundefinedRotate@{scale}{#1,#2}@@}
\xydef@\UnloadRotate@#1{%
 \ifx#1\relax\else\xyunload@{rotation extension}\fi
 \let\xyRotate@@=\xyRotate@
 \let\xySpecialRotate@@=\xySpecialRotate@
 \let\doSpecialRotate@@=\doSpecialRotate@
 \let\xyscale@@=\xyscale@ }
\UnloadRotate@\relax
\xyaddunsupport{rotate}{\UnloadRotate@\relax}
\xydef@\xyrotateSizeMod@ @@{%
 \L@p=\L@c \R@p=\R@c \U@p=\U@c \D@p=\D@c 
 \ifdim\cosDirection\p@>\z@ 
 \R@c=\cosDirection\R@p \L@c=\cosDirection\L@p
 \U@c=\cosDirection\U@p \D@c=\cosDirection\D@p 
 \else
 \R@c=\cosDirection\L@p \L@c=\cosDirection\R@p
 \U@c=\cosDirection\D@p \D@c=\cosDirection\U@p 
 \fi
 \advance\L@c \if-\sinDirection\D@p\else\sinDirection\U@p\fi
 \advance\R@c \if-\sinDirection\U@p\else\sinDirection\D@p\fi
 \advance\U@c \if-\sinDirection\L@p\else\sinDirection\R@p\fi
 \advance\D@c \if-\sinDirection\R@p\else\sinDirection\L@p\fi
 \dimen@ii=\L@c \advance\dimen@ii-\L@p
 \edef\tmp@{\egroup \L@c=\the\L@c \R@c=\the\R@c \U@c=\the\U@c \D@c=\the\D@c
 \dimen@ii=\the\dimen@ii \noexpand\setboxz@h\bgroup
 \noexpand\xyRotate@@{\the\Direction}}\tmp@
 \xydropRotated@ }
\xydef@\xydropRotated@@{%
 \kern\dimen@ii \boxz@ \kern-\dimen@ii \modXYtransform@ \egroup }
\xylet@\xydropRotated@=\xydropRotated@@
\xydef@\xyignoreSizeMod@ @@{\xywarning@{Ignoring rotation}}
\xydef@\xyshape@left@{\xyrotatechar@ v(0,1)@@}
\xydef@\xyshape@right@{\xyrotatechar@ v(0,-1)@@}
\xydef@\xyshearchar@{\xyundefinedRotate@{shearing}}
\xyendinput

cs0304046.extracted_bib
\begin{thebibliography}{10}

\bibitem{tesiAreces}
C.~Areces.
\newblock {\em Logic Engineering. The Case of Description and Hybrid Logics}.
\newblock PhD thesis, ILLC, University of Amsterdam, The Netherlands., 2000.

\bibitem{CardCair1e2}
L.~Caires and L.~Cardelli.
\newblock A {S}patial {L}ogic for {C}oncurrency ({P}art {I} and {II}).
\newblock Part 1: To appear in Journal of Information and Computation special
  issue on TACS 2001. Part2: Proc. CONCUR'2002, LNCS 2421, Springer-Verlag.

\bibitem{CG00:logic-for-MA}
L.~Cardelli and A.~Gordon.
\newblock {Anytime, anywhere --- modal logics for mobile ambients}.
\newblock In {\em Proceedings of POPL '00}, pages 365--377. ACM, 2000.

\bibitem{CG00:mobile-ambients}
L.~Cardelli and A.D. Gordon.
\newblock Mobile ambients.
\newblock {\em Theoretical Computer Science}, 240(1):177--213, 2000.
\newblock An extended abstract appeared in \emph{Proceedings of FoSSaCS '98},
  number 1378 of Lecture Notes in Computer Science, pages 140-155, Springer,
  1998.

\bibitem{chmi88}
K.M. Chandy and J.~Misra.
\newblock {\em Parallel {P}rogram {D}esign: {A} {F}oundation}.
\newblock Addison-Wesley, Reading Mass., 1988.

\bibitem{EhrichDalLibro}
H.-D. Ehrich, C.~Caleiro, A.~Sernadas, and G.~Denker.
\newblock Logics for specifying concurrent information systems.
\newblock In J.~Chomicki and G.~Saake, editors, {\em Logic for Databases and
  Information Systems}, pages 167--198. Kluver Academic Publishers, 1998.

\bibitem{fhmv95}
R.~Fagin, J.~Halpern, Y.~Moses, and M.~Vardi.
\newblock {\em Reasoning {A}bout {K}nowledge}.
\newblock MIT Press, 1995.

\bibitem{denver}
G.~Ferrari, C.~Montangero, L.~Semini, and S.~Semprini.
\newblock Refinement {C}alculus for {M}obility: expressing security policies.
\newblock In J.~Vitek, editor, {\em Workshop on Distributed Object Security},
  Denver, Co, 1999.

\bibitem{adhoc}
G.~Ferrari, C.~Montangero, L.~Semini, and S.~Semprini.
\newblock Ad {H}oc {N}etwork {A}pplications: {S}pecification, {D}esign, and
  {V}erification in mob$_{adtl}$.
\newblock In G.-C. Roman and G.P. Picco, editors, {\em Proc. ICSE'01 Workshop
  on Software Engineering and Mobility}, Toronto, CA, 13,14 May 2001.

\bibitem{mark}
G.~Ferrari, C.~Montangero, L.~Semini, and S.~Semprini.
\newblock Mark, a reasoning kit for mobility.
\newblock {\em Automated Software Engineering}, 9(2):137--150, Apr 2002.

\bibitem{wits00Corto}
G.Ferrari, C.Montangero, L.Semini, and S.Semprini.
\newblock Multiple {S}ecurity {P}olicies in {M}ob$_{adtl}$.
\newblock In {\em Proc. Work. on Issues in the Theory of Security}, Geneva,
  2000.

\bibitem{LogKatz}
S.~Katz and D.~Peled.
\newblock Interleaving set temporal logic.
\newblock {\em Theoretical Computer Science}, 75(3):263--287, 1990.

\bibitem{lprm95}
K.Lodaya, R.Parikh, R.Ramanujam, and P.S.Thiagarajan.
\newblock A {L}ogical {S}tudy of {D}is- tributed {T}ransition {S}ystems.
\newblock {\em Information and Computation}, 119(1):91--118, '95.

\bibitem{Kreger}
H.~Kreger.
\newblock Web {Services Conceptual Architecture}.
\newblock IBM Software Group, May 2001.
\newblock www-4.ibm.com/software/solutions/webservices/pdf/WSCA.pdf.

\bibitem{lamport78}
L.Lamport.
\newblock Time, clocks, and the ordering of events in a distributed system.
\newblock {\em Communications of the ACM}, 21(7):558--565, Jul 1978.

\bibitem{LodRamThi92Corto}
Lodaya, Ramanujam, and Thiagarajan.
\newblock Temporal logics for communicating sequential agents: {I}.
\newblock {\em Int. Journal of Found. of Computer Science}, 3(2):117--159, '92.

\bibitem{loretiTOCL}
M.~Loreti and R.~De Nicola.
\newblock A modal logic for mobile agents.
\newblock ACM Transaction on Computational Logic (to apperar).

\bibitem{masini92}
A.~Masini and A.~Maggiolo-Schettini.
\newblock {TTL}: A formalism to describe local and global properties of
  distributed systems.
\newblock {\em Informatique th\'eorique et Applications/Theoretical Informatics
  and Applications}, 26(2):115--149, 1992.

\bibitem{merz03}
S.~Merz, M.~Wirsing, and J.~Zappe.
\newblock A spatio--temporal logic for the specification and refinement of
  mobile systems.
\newblock In M.~Pezz\'e, editor, {\em Proc. FASE 2003}, volume 2621 of {\em
  Lecture Notes in Computer Science}, pages 87--101. Springer-Verlag, 2003.

\bibitem{tesiAmontanari}
A.~Montanari.
\newblock {\em Metric and Layered Temporal Logic for Time Granularity}.
\newblock PhD thesis, University of Amsterdam, 1996.
\newblock Chapter 3.

\bibitem{isawCorto}
C.~Montangero and L.~Semini.
\newblock Refining by {A}rchitectural {S}tyles or {A}rchitecting by
  {R}efinements.
\newblock In {\em 2nd Int. Software Architecture Workshop, Proc. of the SIGSOFT
  '96 Workshops}, pages 76--79, San Francisco, CA, Oct 1996. ACM Press.

\bibitem{fmics01}
C.~Montangero and L.~Semini.
\newblock Software specification and design: from formal methods to standard
  middleware.
\newblock In {\em Proc. 6th ERCIM Inter. Workshop on Formal Methods for
  Industrial Critical Systems (FMICS'01)}, 2001.

\bibitem{time02}
C.~Montangero and L.~Semini.
\newblock Distributed states logic.
\newblock In {\em 9$^{th}$ International Symposium on Temporal Representation
  and Reasoning}, Manchester, UK, July 2002. IEEE CS Press.

\bibitem{coord99c}
C.~Montangero and L.~Semini.
\newblock Composing {S}pecifications for {C}oordination.
\newblock In P.~Ciancarini and A.~Wolf, editors, {\em Proc. {COORDINATION 99}},
  volume 1594 of {\em LNCS}, pages 118--133, Amsterdam, April 99.
  Springer-Verlag.

\bibitem{CLR2}
Microsoft .NET.
\newblock at http://research.microsoft.com.

\bibitem{CatSynch}
C.~Palamidessi.
\newblock Comparing the expressive power of the synchronous and the
  asynchronous pi-calculus.
\newblock Mathematical {S}tructures in {C}omputer {S}cience. {T}o appear.
\newblock http://www.cse.psu.edu/\~catuscia/papers/pi\_calc/mscs.ps.

\bibitem{PiWo}
Pinter and Wolper.
\newblock A temporal logic for reasoning about partially ordered
  specifications.
\newblock In {\em Proc. 3$^{th}$ ACM Principles of Distributed Computing},
  pages 28--37, Vancouver, B.C., 1984.

\bibitem{Rama96}
R.~Ramanujam.
\newblock Locally linear time temporal logic.
\newblock In {\em Proc. $11^{th}$ IEEE Symp. on Logic In Computer Science},
  pages 118--127. IEEE Computer Society, 1996.

\bibitem{sgarrascico}
L.~Semini and C.~Montangero.
\newblock A {R}efinement {C}alculus for {T}uple {S}paces.
\newblock {\em Science of Computer Programming}, 34:79--140, 1999.

\bibitem{Thiaga94}
P.~S. Thiagarajan.
\newblock A trace based extension of linear time temporal logic.
\newblock In {\em Proceedings, Ninth Annual {IEEE} Symposium on Logic in
  Computer Science}, pages 438--447, Paris, Jul 1994. IEEE Computer Society
  Press.

\bibitem{Thiaga98DVL}
P.~S. Thiagarajan and J.~G. Henriksen.
\newblock Distributed versions of linear time temporal logic: {A} trace
  perspective.
\newblock In W.~Reisig and G.~Rozenberg, editors, {\em Lectures on Petri Nets
  I: Basic Models, Advances in Petri Nets}, volume 1491 of {\em Lecture Notes
  in Computer Science}, pages 643--681. Springer-Verlag, 1998.

\bibitem{CSHARP}
C.~Wille.
\newblock {\em Presenting {C}\#}.
\newblock SAMS Publishing, 2000.

\end{thebibliography}