An Interactive Semantics of Logic Programming
ROBERTO BRUNI
UGO MONTANARI
Dipartimento di Informatica
Universit\`a di Pisa
Corso Italia 40
56125 Pisa
Italia.
FRANCESCA ROSSI
Dipartimento di Matematica
Universit\`a di Padova
Via Belzoni 7
35131 Padova
We apply to logic programming some recently emerging ideas from the field of reduction-based communicating systems, with the aim of giving evidence of the hidden interactions and the coordination mechanisms that rule the operational machinery of such a programming paradigm. The semantic framework we have chosen for presenting our results is tile logic, which has the advantage of allowing a uniform treatment of goals and observations and of applying abstract categorical tools for proving the results. As main contributions, we mention the finitary presentation of abstract unification, and a concurrent and coordinated abstract semantics consistent with the most common semantics of logic programming. Moreover, the compositionality of the tile semantics is guaranteed by standard results, as it reduces to check that the tile systems associated to logic programs enjoy the tile decomposition property. An extension of the approach for handling constraint systems is also discussed.
tp_lp.tex
\documentclass{tlp}
\usepackage{aopmath}

\newtheorem{definition}{Definition}[section]
\newtheorem{example}{Example}[section]
\newtheorem{remark}{Remark}[section]
\usepackage{amssymb}
\usepackage{alltt}
\usepackage[arrow,matrix,frame,curve,cmtip]{xy}\CompileMatrices
\usepackage[english]{babel}
\usepackage{mathrsfs}
\usepackage{pslatex}
\usepackage{url}

\let\from\colon
\let\pto\rightharpoonup
\let\emptyset\varnothing
\let\setminus\smallsetminus

\newcommand{\cell}[4]{#1\raisebox{-.8ex}{\mbox{$\stackrel%
{\textstyle\stackrel{#2}{\longrightarrow}}{\scriptstyle #3}$}}#4}
\newcommand{\trans}[3]{#1\stackrel{#2}{\longrightarrow}#3}
\newcommand{\nat}{\mathbb{N}}
\def\abs#1{\left|#1\right|}
\newcommand{\sbtn}[2]{{#1}/{#2}}
\newcommand{\irule}[2]{\frac{\textstyle\rule[-1.3ex]{0cm}{3ex}#1}%
{\textstyle\rule[-.5ex]{0cm}{3ex}#2}}
\newcommand{\dfun}[3]{#1 \from #2 \to #3}
\newcommand{\eg}{e.g.}
\newcommand{\ie}{i.e.}
\newcommand{\wrt}{w.r.t.}
\newcommand{\cf}{cf.}
\newcommand{\vvdash}{\xymatrix@C=.3pc{{ } \ar@{||-}[r] & { } }}

\newcommand{\Set}{\mathbf{Set}}

\begin{document}
\bibliographystyle{tlp}

\title[Interactive Semantics]
      {An Interactive Semantics of Logic Programming}
\author[R. Bruni, U. Montanari and F. Rossi]
       {ROBERTO BRUNI, UGO MONTANARI\\
        Dipartimento di Informatica, Universit\`a di Pisa,\\
        Corso Italia 40, 56125 Pisa, Italia. \\
        \{\texttt{bruni,ugo}\}\texttt{@di.unipi.it}
       \and
        FRANCESCA ROSSI\\
        Dipartimento di Matematica, Universit\`a di Padova,\\
        Via Belzoni 7, 35131 Padova, Italia. \\
        \texttt{frossi@math.unipd.it}}

\maketitle

\begin{abstract}
 We apply to \emph{logic programming} some recently emerging ideas
 from the field of reduction-based communicating
 systems, with the aim
 of giving evidence of the hidden interactions and the coordination
 mechanisms that rule the operational machinery of such a programming
 paradigm.  The semantic framework we have chosen for presenting our
 results is \emph{tile logic}, which has the advantage of allowing a
 uniform treatment of goals and observations and of applying abstract
 categorical tools for proving the results. As main contributions, we
 mention the finitary presentation of abstract unification, and a
 concurrent and coordinated abstract semantics consistent with the
 most common semantics of logic programming. Moreover, the
 compositionality of the tile semantics is guaranteed by standard
 results, as it reduces to check that the tile systems associated to
 logic programs enjoy the \emph{tile decomposition property}.
 An extension of the approach for handling constraint
 systems is also discussed.
\end{abstract}

\section*{Introduction}

 Logic programming \cite{Llo:FLP} is a foundational research field
 that has been extensively investigated throughout the last 25
 years. It can be said that, in logic programming, theory and practice
 meet together since its very beginning, as each innovation on one
 side contributes many insights to the other side thanks to
 the basic principle of logic programming, which is `writing
 programs by expressing their properties.'
 This symbiosis has also facilitated the study and the prototyping
 of interdisciplinary applications that either extend the `kernel' of
 the framework with additional features or transfer helpful techniques
 from a large variety of paradigms. A typical example is the embedding
 of constraints within logic programming
 \cite{MS:PCI,JM:CLPS}, which retains the declarative and clean semantics of
 logic programming, as well as its typical problem solving features,
 while extending its applicability to many practical
 domains; in fact, constraint logic programming (\textsc{clp}) is now
 considered as a major programming paradigm.

 More interestingly, very often these flows of ideas have been
 profitably bidirectional and continuous, thus allowing one to
 establish strong connections between different areas (bringing useful
 analogies) and also to bridge gaps between different formalisms.

\subsubsection*{Interaction via contextualization and instantiation}

 In this paper, inspired by recent progress in the fields of
 communicating systems and calculi for concurrency, we want to focus
 on an \emph{interactive} view of logic programming. The idea is to
 understand logical predicates as (possibly open) interacting agents whose
 local evolutions are coordinated by the unification engine. In fact,
 the amount of interaction arises from the unification mechanism of
 resolution, as subgoals can share variables and therefore
 `local' progress of a component can influence other components by further
 instantiating such shared variables.
 One central aspect of this view is to understand what kind of
 information we should observe to characterize interaction and how far
 the approach can be extended to deal with different semantic
 interpretations of logic programs.  For example, one interesting
 issue is \emph{compositionality}.  Having a compositional
 semantic framework is indeed very convenient for formal reasoning
 on program properties and can facilitate the development of
 modular programs \cite{BGLM:CSLP,BLM:CMTS,GS:FACS,MP:ALP}.

 We sketch here the main ideas concerning the role played by
 `contexts' in reduction systems, but for a more precise overview we
 invite the interested reader to join us in the little detour, from
 the logic programming world to the process description calculi
 area, inserted in the last part of this introductory
 section (with links to related literature).

 Generally speaking, the issue we focus on is that of equipping a
 reduction system with an interactive semantics. In fact, although
 reduction semantics are often very convenient because of a friendly
 presentation, they are not compositional `in principle.'  The problem
 is that they are designed having in mind a progressive reduction of
 the initial state to a suitable normal form, \ie, one focuses
 on a completely specified system that can be studied in
 isolation from all the rest. In logic programming, this would
 correspond to studying the refutation of ground goals only and to
 develop an \emph{ad-hoc} system to this aim.  Then, if one wants to
 study the semantics of partially specified components the framework
 is no longer adequate and some extensions become necessary. For
 example, in process description calculi, a partially specified
 component can be a process term (called \emph{open process} or
 \emph{context}) that contains suitable process variables representing
 generic subprocesses. However, also a closed term (\ie, without free
 process variables) can be considered an open system when it evolves
 as part of a broader system, by
 interacting with the environment.  In logic
 programming we can distinguish two main kinds of openness and
 interaction. A first kind is due to goals with variables (rather than
 ground) that can obviously be regarded as partially specified
 systems. A second kind consists of regarding an atomic
 goal as part of a larger conjoined goal with which it must interact.

 The obvious way to deal with partially specified components is to
 transform the problem into the reduction case, which we know how to
 solve. This means that (1) the variables of open
 processes will be instantiated in all possible ways to obtain closed
 systems that can be studied; (2) in order to study the semantics of
 closed subprocesses we will insert them in all possible
 contexts and then study their reductions.  Moreover, the
 operations of contextual and instantiation closure can be rendered
 dynamically, provided that one defines a \emph{labeled transition
 system} (\textsc{lts}) whose labels record the information on the
 performed closure, and this has originated the idea of observing
 contexts and instantiations (sometimes called \emph{external} and
 \emph{internal} contexts, respectively).

 Even if these views can look semantically adequate, it can
 be noted, as their main drawback, that they are not applicable in
 practice, because all considered closures are infinitary.
 The situation can be improved if one is able to identify a small
 finite set of contexts and/or instances that contains all useful
 information, since this can make the approach operationally
 satisfactory. While a general methodology for accomplishing this task
 in  communicating and mobile calculi is difficult to find
 (see \eg, \cite{LM:DBCRS}), we think that logic programming
 represents the perfect situation where it is possible to fully develop
 the closure approach.

 When dealing with the interactive view of logic programs, the idea is
 that unification is the basic action taking place during
 computation, and therefore the observed information must rely on such
 an action. We have seen that two kinds of closure can be
 distinguished that are dual to each other, namely
 \emph{contextualization} and \emph{instantiation}. The former can be
 used to embed components in a larger environment, while the latter
 serves to specialize an open system to some particular instance.

 We shall concentrate our efforts on \emph{pure} logic
 programming (\ie, classical Horn clauses, without any additional
 `gadgets'). Hence contextualization corresponds to putting the goal
 in conjunction with other goals,\footnote{In pure logic programming,
 contextualization does not provide any
 additional information on the possible reductions, as the head
 of each clause consists of only one predicate. The situation
 would be different if generalized multi-head Horn clauses were
 considered, a topic that will be discussed in the conclusions, or
 if second order logic were considered (other predicate contexts
 should be considered beside conjunction).}
 \ie, given a goal $G$ we should
 put it in the context $\_\wedge G'$ for all possible $G'$.
 With respect to instantiation, our proposal is to regard the computed
 substitutions for the variables in the (sub)goals as observable
 internal contexts, which further instantiate the system
 components. Thus, given a goal $G$, we can apply the
 substitution $\sigma$ to the free variables of $G$ and study the
 consequent changes in the semantics.

 The analogy and distinction between internal and external contexts
 become clear if we look at the term algebra over a signature
 $\Sigma$ from a categorical perspective: the objects of the category
 are underlined natural numbers, an $n$-tuple of terms over $m$
 variables corresponds to an arrow from $\underline{m}$ to
 $\underline{n}$, and composition of arrows $t_1\from \underline{m}
 \to \underline{k}$ and $t_2 \from \underline{k} \to \underline{n}$
 is given by substituting the $k$ variables in $t_2$ by the corresponding
 terms in the tuple $t_1$. Then, composing to the right means
 inserting in a context, while composing to the left means providing
 an internal context (\eg, $t_2$ above is external to $t_1$, while
 $t_1$ is internal to $t_2$).

\subsubsection*{Tile logic as a semantic framework}

 For pursuing this research programme, we have chosen to rely on
 \emph{tile logic} \cite{GM:RRCCS,GM:TM} that can provide a convenient
 abstract computational model for logic programming, where many of the
 discussed aspects can be suitably represented and managed.

 The tile framework takes inspiration from and bears many analogies
 with various \textsc{sos} formats
 \cite{Plo:SAOS,DeS:HLSD,BIM:BCBT,GV:SOSBC,Ber:CTSOS},
 \emph{context systems} \cite{LX:CTOSC},
 \emph{structured transition systems} \cite{CM:ASSTS},
 and \emph{rewriting logic} \cite{Mes:CRL}. It allows to define models
 that are compositional both in `space' (\ie, according to the
 structure of the system) and in `time' (\ie, according to the
 computation flow). In particular, tile logic extends rewriting logic
 with a built-in mechanism, based on observable effects, for
 coordinating local rewrites. The effects are in some sense the
 counterparts of labels in \textsc{lts} operational semantics.
 However, since tiles
 are designed for dealing with open states (as opposed to the ordinary
 `ground' view of \textsc{lts}'s generated from \textsc{sos} rules),
 they seem more apt for many
 applications. The idea is to employ a set of rules (called
 \emph{tiles}) to define the behavior of partially specified
 components (\ie, components that can contain variables), called
 \emph{configurations}, only in terms of the possible interactions
 with the internal/external environment.
 In this way, the behavior of a system must be
 described as a coordinated evolution of its local
 subconfigurations. The name `tile' is due to the graphical appearance
 of such rules, which have the form in Figure~\ref{atilefig}, also
 written $\alpha:\cell{t}{u}{v}{s}$, stating that the \emph{initial
 configuration} $t$ evolves to the \emph{final configuration} $s$ via
 the tile $\alpha$, producing the \emph{effect} $v$, which can be
 observed by the rest of the system, but such a step is allowed only
 if the subcomponents of $t$ (\ie, the arguments to which $t$ is
 connected via its input interface) evolve to the subcomponents of
 $s$, producing the effect $u$, which acts as the \emph{trigger} for
 the application of $\alpha$. Triggers and effects are called
 \emph{observations} and tile vertices are called
 \emph{interfaces}. The arrows $t$, $u$, $v$ and $s$ form the
 \emph{border} of $\alpha$.

\begin{figure}[t]
\begin{center}
$\xymatrix@C=6pc@R+1pc{
 *[o]=<.5pc>{\ }\drop\cir{}
 \ar[r]^{t}
 \ar[d]_{u}
 \ar@{}[rd]|{\alpha}
 \ar@<2.5pc>@{}[r]|{\mathrm{initial}}
 \ar@<1.5pc>@{}[r]|{\mathrm{configuration}}
 \ar@<-2.5pc>@{}[d]|{\mbox{trigger}}
 \POS[]+<-2pc,2.5pc>\drop{\mathit{initial}}
 \POS[]+<-2pc,1.5pc>\drop{\mathit{input}}
 \POS[]+<-2pc,.5pc>\drop{\mathit{interface}}
 &
 *[o]=<.5pc>{\ }\drop\cir{}
 \ar[d]^{v}
 \ar@<2.5pc>@{}[d]|{\mbox{effect}}
 \POS[]+<2pc,2.5pc>\drop{\mathit{initial}}
 \POS[]+<2pc,1.5pc>\drop{\mathit{output}}
 \POS[]+<2pc,.5pc>\drop{\mathit{interface}}
 \\
 *[o]=<.5pc>{\ }\drop\cir{}
 \ar[r]_{s}
 \ar@<-1.5pc>@{}[r]|{\mathrm{final}}
 \ar@<-2.5pc>@{}[r]|{\mathrm{configuration}}
 \POS[]-<2pc,.5pc>\drop{\mathit{final}}
 \POS[]-<2pc,1.5pc>\drop{\mathit{input}}
 \POS[]-<2pc,2.5pc>\drop{\mathit{interface}}
 &
 *[o]=<.5pc>{\ }\drop\cir{}
 \POS[]+<2pc,-.5pc>\drop{\mathit{final}}
 \POS[]+<2pc,-1.5pc>\drop{\mathit{output}}
 \POS[]+<2pc,-2.5pc>\drop{\mathit{interface}}
}$
\end{center}
\caption{A tile.}
\protect\label{atilefig}
\end{figure}


 Tiles can be composed horizontally, vertically, and in parallel
 to generate larger steps. The three compositions are
 illustrated in Figure~\ref{threecomptile}. Horizontal composition
 yields rewriting synchronization (\eg, between the evolution of
 an argument via $\alpha$ and the evolution of its
 environment via $\beta$, as the effect of $\alpha$
 provides the trigger for $\beta$). Vertical
 composition models the sequential
 composition of computations.  The operation of parallel composition
 corresponds to building concurrent steps, where two (or more)
 disjoint configurations can concurrently evolve. Of course, the
 border of a concurrent step is the parallel composition of the
 borders of each component of the step.

 Given a set of basic tiles, the associated \emph{tile logic} is
 obtained by adding some canonical `auxiliary' tiles and then closing
 by (the three kinds of) composition both
 auxiliary and basic tiles. As an example, auxiliary tiles may be
 introduced that accommodate isomorphic transformations of interfaces,
 yielding consistent rearrangements of configurations and observations
 \cite{BMM:PTTL,Bru:TL}.

\begin{figure}[t]
\begin{center}
$\vcenter{\xymatrix@R-1pc@C+1pc{
 {\circ} \ar[r] \ar[d] \ar@{}[rd]|{\alpha} &
 {\circ} \ar[r] \ar[d] \ar@{}[rd]|{\beta} &
 {\circ} \ar[d] \\
 {\circ} \ar[r] &
 {\circ} \ar[r] &
 {\circ} }}$
\hfill $\vcenter{\xymatrix@R-1pc@C+1pc{
 {\circ} \ar[r] \ar[d] \ar@{}[rd]|{\alpha} &
 {\circ} \ar[d] \\
 {\circ} \ar[r] \ar[d] \ar@{}[rd]|{\beta} &
 {\circ} \ar[d] \\
 {\circ} \ar[r] &
 {\circ} }}$
\hfill $\vcenter{\xymatrix@R-2pc@C-1pc{
 & {\circ} \ar[rr] \ar[dd] & &
 {\circ} \ar[dd] \\
 {\circ} \ar[rr] \ar[dd] & &
 {\circ} \ar[dd] \ar@{}[ru]|{\beta} \\ &
 {\circ} \ar[rr] & & {\circ} \\
 {\circ} \ar[rr] \ar@{}[ru]|{\alpha} &
 {\ } &
 {\circ} }}$
\end{center}
\caption{Horizontal, vertical and parallel tile
compositions.} \protect\label{threecomptile}
\end{figure}

 Tile logic deals with algebraic structures on configurations that can
 be different from the ordinary, tree-like presentation of terms
 employed in most \textsc{lts}'s. All these structures, ranging from
 graphs and term graphs to partitions and relations, give rise to
 monoidal categories and, therefore, possess the two basic operations
 needed by tile configurations. This is very convenient, as the models
 of the logic can be formulated in terms of \emph{monoidal double
 categories}. In this paper, we assume the reader to be familiar with
 the basic concepts of category theory, though we shall not push their
 usage too far (employing categories in a mild way) and shall give
 informal explanations of most categorical constructs introduced.

 Likewise context systems \cite{LX:CTOSC} and \emph{conditional
 transition systems} \cite{Ren:BOT}, tile logic allows one to reason
 about terms with variables \cite{BFMM:BC}. This means, \eg, that
 trace semantics and bisimilarity can be extended straightforwardly to
 open terms by taking as observation the pair $\langle
 \mathit{trigger}, \mathit{effect}\rangle$, whereas ordinary
 \textsc{lts}'s deal with transitions from closed terms to closed
 terms for which triggers are trivial identities. The compositionality
 of abstract semantics (either based on traces or on bisimilarity) can
 then be guaranteed by algebraic properties of the tile system or by
 suitable specification formats \cite{BFMM:BC}. In particular, we
 shall see that the \emph{decomposition property} \cite{GM:TM} yields
 a very simple proof of the compositionality of the tile logic
 associated to a logic program.

\subsubsection*{The tile approach to logic programming}

 A well-known fact (\cf\ the discussion in Section~\ref{RVPsec}
 and \cite{BR:CUA,CM:ASSTS}) that is exploited in the construction we
 propose is that in categorical terms the construction of the
 \emph{most general unifier} (mgu) between a subgoal and the head
 of a clause can be expressed as a \emph{pullback} in the
 syntactic category associated to the signature under
 consideration. One of the contributions of this paper is in fact
 to provide a constructive, modular way of building the pullback
 construction. It is similar to the ordinary unification mechanism
 but formulated in a completely abstract way by means of
 coordination rules. This translates immediately in terms of tile
 logic, completing the first part of our research programme, that
 is, understanding the extent of interaction we shall observe,
 and expressing it in a formal system.

 For the rest, we define a transformation from logic programs to
 tile systems by associating a basic tile to each Horn clause in the
 program.  Then, the resulting tile models are shown to provide a
 computational and semantic framework where the program and its
 tile representation yield exactly the same set of computed answer
 substitutions for any goal. It is remarkable that all
 aspects concerning the control flow are now automatically
 handled by tiles (e.g. generation of fresh variables, unification,
 construction of resolvents).

 One of the advantages of tile logic is to make evident the duality
 between contextualization and instantiation, still being able to deal
 in a uniform way with both perspectives. The same thing can be said
 for the uniform treatment of configurations and observations that
 facilitates the use of contexts as labels, providing many insights on
 the way the basic pieces can be put together to form a whole
 computation.

 The tile presentation of a program allows us not only to
 transfer to logic programming abstract semantic equivalences
 based on traces and bisimilarity, but also to show that
 these equivalences are compositional (\ie, they are
 \emph{congruences}) via an abstract proof based on the
 decomposition property of the underlying tile system. More
 concretely, denoting by $\sim$ any of the two equivalences (on
 goals) mentioned above, we have almost for free that if
 $G_1\mathrel{\sim} G_2$, then: (1) $\sigma(G_1) \mathrel{\sim}
 \sigma(G_2)$ for any substitution $\sigma$, and (2) $G_1\wedge G
 \mathrel{\sim} G_2 \wedge G$ for any goal $G$.
 (This lifts also to the case where the simpler `success' semantics
 is considered.)

 The application of our `tile' techniques to logic programming can
 serve as a basis for establishing useful connections and studying
 analogies with the process calculi paradigm. For example,
 it comes out that there is a strong resemblance between the
 parallel operator of many process calculi and the conjunction
 operator on goals. As another example, it would be interesting to
 transfer to logic programming concepts like `explicit substitution'
 and `term graph', which play important roles in the implementation
 of distributed systems.

\subsubsection*{A digression: Sources of inspiration}

 Before illustrating the organization of the material, we want to
 explain more precisely the intuition that motivated our research on
 interactive semantics for reduction systems and its application to
 logic programming.
 As already pointed out, our sources of inspiration mostly come
 from contributions in the theory of communicating systems.  The
 first fact to note is that there are two well recognized and
 widely studied schools of thought for giving semantics to
 process description calculi, namely via \emph{reduction} rules (especially
 popular after Berry and Boudol's \textsc{cham} \cite{BB:CAM})
 and via \textsc{lts}'s.

 The first approach relies on the assumption that it is possible to
 observe and manipulate the global state of a complex system. In particular,
 the current state can be inspected for finding a
 \emph{redex}, \ie, a candidate for the application of a reduction step. The
 redexes usually coordinate the activity of several logically distinct
 components of the system, and therefore, to some extent, the
 reduction step synchronizes their local activities into a global
 atomic move. For dealing with compositionality, one would
 be interested in deriving the semantics of a whole entity in terms of
 the semantics of its very basic component parts, which can become a
 hard task when reductions are global actions.  The
 problem is that a redex may lie in between a component and the
 external environment, and therefore to understand the behavior of a
 component as a stand alone entity, we have to consider its
 interactions with all possible environments, in the style of
 \emph{testing semantics} \cite{dNH:TEP}.

 Instead, the point of view of observational equivalences based on
 \textsc{lts} semantics is to use \emph{observations} (transition labels)
 to derive observational equivalences on processes,
 as \eg, \emph{bisimilarity} \cite{Par:CAIS,Mil:CCS}. Moreover, the
 formats for specifying \textsc{lts} operational semantics can exploit
 inductively the structure of a complex state to define its semantics
 in terms of the actions that can be accomplished by
 subcomponents, guaranteeing compositionality properties
 like `bisimilarity is a congruence.'

 One emerging idea to provide reduction semantics with an
 interactive, observational view is that of `observing contexts'
 \cite{Mil:PPC,MS:DCPB,Mil:CFI,Ber:CTSOS,Sew:RRBC,LM:DBCRS,CLM:CECAG}.
 Basically, starting from a reduction system, one has to define
 the semantics of a local component by embedding it in all
 possible contexts and by considering those contexts as
 observations. Then, when several components are assembled
 together, it is possible to predict the semantics of the result
 simply by inspecting the behaviors of each component in the
 environment contributed by all the remaining components.  This
 approach gives rise to a special kind of bisimulation, called
 \emph{dynamic bisimilarity} \cite{MS:DCPB}, which is the
 coarsest congruence that is also an ordinary bisimulation.
 This approach
 corresponds to some extent to give the possibility to
 dynamically reconfigure the system and has also some
 applications to open ended systems \cite{BMS:OES}.
 Though theoretically sound, this solution
 leaves open many operational questions, because the semantics
 must take into account all possible contexts.

 Many people attempt to define a general and clever
 methodology for passing from reduction semantics to
 (compositional) \textsc{lts} semantics
 \cite{Sew:RRBC,LM:DBCRS,CLM:CECAG}. In particular, Leifer and
 Milner show in \cite{LM:DBCRS} that a minimal set of contexts
 is definable whenever sufficiently many \emph{relative pushouts}
 exist in the category of configurations. Roughly speaking, it
 must be the case that for any configuration $t$ and any reduction
 rule with which $t$ can react in a suitable
 environment $C$, then there exists a minimal observable context
 $C'$ that makes such reduction possible.

 Dual to the problem of `contextualization' is the problem of
 `instantiation.' It arises when one wants to extend the
 compositionality from ground processes to open processes.
 In fact, the equivalence on open terms is usually defined
 via the equivalence on closed terms, by saying that two
 contexts are equivalent if their closures
 under all possible ground instantiations are so. Again, it is
 preferable to avoid the instantiation closure and find a more compact
 way to enforce the modularity of the framework. This issue has been
 pursued in two recent works \cite{Ren:BOT,BFMM:BC} for providing
 general specification formats that guarantee the compositionality of
 open systems. They are based on the idea of recording in the
 transition labels not only the effects of each move, but also the
 triggers provided by the subcomponents for applying the transition to
 the global state. Consequently, in the `dynamic' version, instantiation
 becomes a sort of `internal contextualization' and
 substitutions can be used as labels (in the trigger part).

 In the case of logic programming, many of the above concepts find a
 natural meaning. Thus, \eg, goal instantiation
 is a relevant internal contextualization that can
 modify the semantics of the goal (\eg, by making impossible the
 unification with the head of a clause which can otherwise be
 applicable), while external contextualization is given by conjunction with
 other goals (it can be relevant when multi-headed
 clauses are allowed).

\subsubsection*{Structure of the paper}

 We fix the notation and recall the necessary
 background in Section~\ref{Bsec}. Due to the heterogeneity of the
 material, its presentation is separated in four
 parts: Section~\ref{Nsec} summarizes a few elementary
 definitions about signatures, substitutions and Horn clauses;
 Section~\ref{OSsec} recalls the operational machinery of logic
 programming; Section~\ref{TLsec} presents the tile notation and
 the categorical models based on double categories;
 Section~\ref{ATsec} presents the concepts of Section~\ref{Nsec}
 under a different light (exploiting Lawvere's pioneering work
 \cite{Law:FSAT}), which will offer a more convenient notation
 for representing logic programs in tile logic. While the
 contents of Sections~\ref{Nsec} and~\ref{OSsec} are standard,
 the notions recalled in Sections~\ref{TLsec} and~\ref{ATsec}
 might be not so familiar to the logic programming community.

 In Section~\ref{RVPsec} we recall the ways in which
 most general unifiers, equalizers and pullbacks intertwine.
 This should provide the
 reader with the formal knowledge for understanding the technical
 details of the correspondence between unification in logic
 programming and coordination via pullback tiles, which is
 explained in Section~\ref{DCPsec}. In particular, we think that
 the results in Section~\ref{FPPsec} are the key to the
 application of tiles to logic programming.

 Section~\ref{TSLPsec} exploits the notation and results from
 Section~\ref{DCPsec} to establish the connection between logic
 programming and tile logic. The transformation is described in
 Section~\ref{FLPTLTsec}, together with a simple example that
 illustrates the correspondence between the two views. The main
 advantages of the tile approach are examined separately in
 Section~\ref{FCTTsec} (connections with ongoing research on process
 calculi), Section~\ref{ROSsec} (formal correspondence with ordinary
 semantics), Section~\ref{GCsec} (goal compositionality via abstract
 congruences), Section~\ref{THREEsec} (comparison between
 goal equivalences obtained by considering different instantiation
 closures), and in Section~\ref{DTsec} (insights on concurrency and
 coordination). The compositionality of the resulting framework
 strongly depends on the representation results of
 Section~\ref{FPPsec}, that allow one to decompose a complex
 coordination along its basic bits.

 While the paper focuses on pure logic programs, we think that the
 approach can be extended to take into account many variants of logic
 programming. Some of these extensions are discussed in
 Section~\ref{CLPsec} (devoted to constraint logic programming)
 and in the concluding section.

\section{Background}\label{Bsec}

\subsection{Notation}\label{Nsec}

 Let $\Sigma$ be a two sorted signature over the set of sorts
 $\{\mathsf{t},\mathsf{p}\}$. Provided that
 the sort $\mathsf{p}$ does not appear in the arity of any
 operator, we call $\Sigma$ a \emph{logic
 program signature} and we denote by $\Sigma_\Phi =
 \bigcup_n\Sigma^n_\Phi$ and $\Sigma_\Pi = \bigcup_n\Sigma^n_\Pi$
 the ranked sets of \emph{function symbols} $\dfun
 f{\mathsf{t}^n}{\mathsf{t}}$ and of \emph{predicate symbols}
 $\dfun p{\mathsf{t}^n}{\mathsf{p}}$, respectively.

 As usual, given a set $X$ of (term) variables, we denote with
 $\mathbb{T}_\Sigma(X)$ the free $\Sigma$-algebra generated by $X$.  A {\em
 term over} $X$ is an element of $\mathbb{T}_{\Sigma_\Phi}(X)$. The set of all
 \emph{ground terms} (\ie, terms without variables) is called the {\em
 Herbrand universe for} $\Sigma$. An \emph{atomic formula over} $X$ has
 the form $p(t_1,\ldots,t_n)$ where $p\in\Sigma^n_\Pi$ and
 $t_1,\ldots,t_n$ are terms over $X$. A \emph{conjunctive formula} is
 just a tuple of atomic formulas. The set of all ground atomic
 formulas is called the \emph{Herbrand base} for $\Sigma$.

 If $X = \{x_1,\ldots,x_n\}$ and $Y$ are sets of variables, a {\em
 substitution from $Y$ to $X$} is a function
 $\dfun\sigma{X}{\mathbb{T}_{\Sigma_\Phi}(Y)}$, usually denoted by
 $[\sbtn{\sigma(x_1)}{x_1},\ldots,\sbtn{\sigma(x_n)}{x_n}]$.  If $t$
 is a term over $X$ and $\sigma$ is a substitution from $Y$
 to $X$ then the term over $Y$ obtained by {\em
 simultaneously} substituting in $t$ all the occurrences of the
 variables in $X$ with their images through $\sigma$ is called the {\em
 application of $\sigma$ to $t$} and written $\sigma;t$.

 If $\sigma$ is a substitution from $Y$ to $X$ and $\sigma'$ is a
 substitution from $Z$ to $Y$, their \emph{composition} is the
 substitution $\sigma';\sigma$ from $Z$ to $X$ defined by applying
 $\sigma'$ to each image of the variables in $X$ through $\sigma$.  A
 substitution $\sigma$ is said to be \emph{more general} than $\sigma'$
 if there exists a substitution $\theta$ such that $\sigma' = \theta;\sigma$.
 It is worth noticing that since substitution composition is
 associative with the identity substitutions
 $[\sbtn{x_1}{x_1},\ldots,\sbtn{x_n}{x_n}]$ as neutral elements, then
 substitutions form the arrows of a category having finite sets of
 variables as objects.

 Two terms (also atomic formulas) $t$ and $s$ \emph{unify} if there
 exists a substitution $\theta$ such that $\theta;t = \theta;s$. In
 this case $\theta$ is called a \emph{unifier} of $t$ and $s$. If $t$
 and $s$ unify there exists also a \emph{most general unifier} (unique
 up to variable renaming), \emph{mgu} for short.

 The mgu can be computed by employing, \eg, the following
 (nondeterministic) algorithm that operates on a set of equations (at
 the beginning the set is the singleton $\{t=s\}$).

{\em
\begin{itemize}
\item
 Apply one of the following steps until stability is reached:
 \begin{enumerate}
 \item
  eliminate the equation $x=x$ from the set for some variable $x$;
 \item
  eliminate the equation $f(t_1,\ldots,t_n) = f(s_1,\ldots,s_n)$ from
  the set and insert the equations $t_1=s_1$,\ldots,$t_n=s_n$ in it;
 \item
  if the equation $x=t$ with $x$ a variable not appearing in $t$ is
  contained in the current set, apply the substitution $[\sbtn{t}{x}]$
  to all the other equations (but do not remove $x=t$).
  \end{enumerate}
\end{itemize}
}

 The algorithm always terminates. It terminates with success if
 the resulting set of equations has the form $\{x_1 =
 t_1,\ldots,x_n=t_n\}$ with $x_i$ not appearing in $t_j$ for all
 $i,j\in [1,n]$. The algorithm can be efficiently computed if it
 cyclically executes the sequence of steps
 1, 3 (with $x=y$), 2, 3 (with $x=t$).


\subsection{Syntax and operational semantics of logic programs}\label{OSsec}

 In this section we briefly recall the basics of the operational
 semantics of logic programs. We refer to \cite{Llo:FLP} for a more
 detailed introduction to the subject.

 A \emph{definite Horn clause} $c$ is an expression of the form

\[H \mathrel{:-} B_1,\ldots,B_n\]

\noindent
 with $n\geq 0$, where $H$ is an atomic formula called
 the \emph{head} of $c$ and $\langle B_1,\ldots,B_n\rangle$ is a
 (conjunctive) formula called the \emph{body} of $c$.
 A logic program $\mathcal{P}$ is a finite collection of clauses
 $\{c_1,\ldots,c_m\}$.

 A \emph{goal} is an expression of the form

\[\mathrel{?-} A_1,\ldots,A_k\]

\noindent
 with $k\geq 0$, where $G \mathrel{\equiv} \langle
 A_1,\ldots,A_k\rangle$ is a (conjunctive) formula and the $A_i$'s are
 the \emph{atomic subgoals} of $G$. If $k=0$, then $G$ is called the
 \emph{empty goal} and is denoted by `$\Box$.'

 Given a goal $G \mathrel{\equiv} \langle A_1,\ldots,A_k\rangle$ and a
 clause $c\equiv H \mathrel{:-} B_1,\ldots,B_n$ (with all variables in the
 latter possibly renamed to avoid confusion with those in $G$) an
 \emph{(SLD)-resolution step} involves the selection of an atomic goal
 $A_i$ such that $H$ and $A_i$ unify and the construction of their mgu
 $\theta$. The step leads to a new goal

\begin{eqnarray*}
 G'
 & \mathrel{\equiv} &
 \theta;\langle A_1,\ldots,A_{i-1},
                B_1,\ldots,B_n,
                A_{i+1},\ldots,A_k\rangle \\
 & \mathrel{\equiv} &
                \theta;A_1,\ldots,\theta;A_{i-1},
                \theta;B_1,\ldots,\theta;B_n,
                \theta;A_{i+1},\ldots,\theta;A_k
\end{eqnarray*}

\noindent
 which is called the \emph{resolvent} of $G$ and $c$. In this case we
 say that $G'$ is \emph{derived from $G$ and $c$ via $\theta$} and we
 write $G\Rightarrow_{c,\theta} G'$ or simply $G\Rightarrow_{\theta}
 G'$.

 Given a logic program $\mathcal{P} = \{c_1,\ldots,c_m\}$ and a goal
 $G_0$, an {\em (SLD-)derivation} of $G_0$ in $\mathcal{P}$ is a
 (finite or infinite) sequence $G^0,G^1,G^2,\ldots$ of goals, a
 sequence $c_{i_1},c_{i_2},\ldots$ of (renamed) clauses and a sequence
 $\theta_1,\theta_2,\ldots$ of mgu's such that $G^{i+1}$ is derived
 from $G^i$ and $c_{j_i}$ via $\theta_{i}$.  An
 \emph{(SLD-)refutation} of $G_0$ is a finite derivation of $G_0$
 ending with the empty goal. In this case the substitution $\theta =
 (\theta_l;\cdots;\theta_1)_{\mid Var(G)}$ is called a {\em computed
 answer substitution} for $G$, written $G\Rightarrow^*_\theta
 \Box$. The `small-step' operational semantics is formalized in
 Table~\ref{smcasruletab} (but in the rule for atomic goal we must be
 certain that $\rho$ renames the variables in the clause by globally
 fresh names).

\begin{table}
\caption{Operational rules for SLD-resolution (small step
semantics).} \protect\label{smcasruletab}
\begin{tabular}{ccl}
\hline \hline
 $\irule{}
        {\mathcal{P}\vvdash \Box,G\Rightarrow_{id} G}\ \ \
  \irule{}
        {\mathcal{P}\vvdash G,\Box\Rightarrow_{id} G}$ & & empty goal \\
\\
 $\irule{(H \mathrel{:-} F) \in \mathcal{P}\ \
         \sigma = \mathrm{mgu}(A,\rho;H)}
        {\mathcal{P}\vvdash A\Rightarrow_{\sigma}
                            \sigma;\rho;F}$ & & atomic goal \\
\\
 $\irule{\mathcal{P}\vvdash G\Rightarrow_{\sigma}F}
        {\mathcal{P}\vvdash G,G'\Rightarrow_{\sigma}
                            F,(\sigma;G')}\ \ \
  \irule{\mathcal{P}\vvdash G\Rightarrow_{\sigma}F}
        {\mathcal{P}\vvdash G',G\Rightarrow_{\sigma}
                            (\sigma;G'),F}$ & & conjunctive goal \\
\hline \hline
\end{tabular}
\end{table}

 The inductive definition of computed answer substitution and
 refutation in the `big-step' style is given by the rules in
 Table~\ref{casruletab}. The notation $\mathcal{P}\vdash_{\theta} G$
 means that $\mathcal{P}\vvdash G \Rightarrow^*_\theta \Box$, \ie,
 that the goal $G$ can be refuted by using clauses in the program
 $\mathcal{P}$. The first rule says that the empty goal can always be
 refuted with the empty computed answer substitution $\epsilon$. The
 second clause says that an atomic goal can be refuted provided that
 it can be unified with the head $H$ of a clause (suitably renamed by
 $\rho$ to avoid name conflicts with $A$) in the program $\mathcal{P}$
 via the mgu $\sigma$ and that the goal obtained by applying $\sigma$
 to the (renamed) body $F$ of the clause can be refuted with $\theta$.
 The third rule says that a conjunctive goal can be refuted provided
 that its leftmost subgoal can be refuted first with $\sigma$, and
 then the goal obtained by applying $\sigma$ to the other subgoals can
 be refuted with $\theta$. Although imposing a sequentialization in
 the resolution process can appear as an arbitrary choice, the fact
 that refutation involves finite derivations and the well known
 switching lemma guarantee the completeness of the formal system.

\begin{table}
\caption{Operational rules for SLD-resolution (big step
semantics).} \protect\label{casruletab}
\begin{tabular}{rcl}
\hline \hline
 $\irule{}{\mathcal{P}\vdash_{\epsilon} \Box}$ & & empty goal \\
\\
 $\irule{(H \mathrel{:-} F) \in \mathcal{P}\ \
         \sigma = \mathrm{mgu}(A,\rho;H)\ \
         \mathcal{P}\vdash_{\theta} \sigma;\rho;F}
        {\mathcal{P}\vdash_{\theta;\sigma} A}$ & & atomic goal \\
\\
 $\irule{\mathcal{P}\vdash_{\sigma} A\ \
         \mathcal{P}\vdash_{\theta} \sigma;F}
        {\mathcal{P}\vdash_{\theta;\sigma} A,F}$ & & conjunctive goal \\
\hline \hline
\end{tabular}
\end{table}

\subsection{Double categories and tile logic}\label{TLsec}

 The point of view of tile logic \cite{GM:TM,Bru:TL} is that the
 dynamics of a complex system can be better understood if we reason in
 terms of its basic components and of the interactions between
 them. Therefore, reductions must carry observable information about
 the triggers and the effects of the local step. This extends the
 point of view of rewriting logic, where reductions can be freely
 nested inside any context (and also freely instantiated): In tile
 logic, contextualization and instantiation are subordinated to the
 synchronization of the arguments with the environment, \ie, the
 effect of the tile defining the evolution of the former must provide
 the trigger for the evolution of the second. When the coordination is
 not possible, then the step cannot be performed.

 An abstract account of the connections between states and
 dynamics can be given via (monoidal) \emph{double
 categories}, by exploiting their two-fold representation: one
 dimension is for composing states and the second dimension is
 for composing computations. In fact, the models of tile logic are
 suitable double categories \cite{GM:TM,BMM:SMCDC}, and the basic
 tiles of a tile system provide a finitary presentation ---
 which is more convenient to work with --- of the initial model.

 Since we do not want to introduce unnecessary complexity overhead to
 readers not acquainted with double categories, we will present a
 gentle introduction to the subject. For more details we refer to
 \cite{Ehr:CS,Ehr:CS2,MM:TLRL,BMM:PTTL,BMM:SMCDC}.

 A double category contains two categorical structures, called
 \emph{horizontal} and \emph{vertical} respectively, defined over the
 same set of cells. More precisely, double categories admit the
 following na\"\i ve definition.

\begin{figure}[t]
\begin{center}
$\xymatrix{
 {o_0} \ar [r]^{h_0} \ar @{} [dr]|{A} \ar [d]_{v_0} &
 {o_1} \ar [d]^{v_1} \\
 {o_2} \ar [r]_{h_1} &
 {o_3} }$
\end{center}
\caption{Graphical representation of a cell.}
\protect\label{defcell}
\end{figure}


\begin{definition}[Double Category]\label{doubcat}
 A \emph{double category} $\mathcal{D}$ consists of a collection
 $o,o_0,o',\ldots$ of \emph{objects}, a collection $h,h_0,h',\ldots$
 of \emph{horizontal arrows}, a collection $v,v_0,v',\ldots$ of
 \emph{vertical arrows} and a collection $A,B,C,\ldots$ of
 \emph{double cells} (also called \emph{cells}, for short).

\begin{itemize}
\item
 Objects and horizontal arrows form the \emph{horizontal 1-category}
 $\mathcal{H}$, with identity $id_o$ for each object $o$, and
 composition $\_*\_$.

\item
 Objects and vertical arrows form also a category, called the
 \emph{vertical 1-category} $\mathcal{V}$, with identity $id_o$ for
 each object $o$, and composition $\_\cdot\_$.

\item
 Cells are assigned \emph{horizontal source} and \emph{target} (which
 are vertical arrows) and \emph{vertical source} and \emph{target}
 (which are horizontal arrows); furthermore sources and targets must
 be \emph{compatible}, in the sense that they must satisfy the
 equalities on source and target objects graphically represented by
 the square-shaped diagram in Figure~\ref{defcell}, for which we use
 the notation $A:\cell{h_0}{v_0}{v_1}{h_1}$.

\item
 Cells can be composed both horizontally ($\_*\_$) and vertically
 ($\_\cdot\_$) as follows: given $A:\cell{h_0}{v_0}{v_1}{h_1}$,
 $B:\cell{h_2}{v_1}{v_2}{h_3}$, and
 $C:\cell{h_1}{v_3}{v_4}{h_4}$, then $A *
 B:\cell{h_0*h_2}{v_0}{v_2}{h_1*h_3}$, and $A\cdot
 C:\cell{h_0}{v_0\cdot v_3}{v_1\cdot v_4}{h_4}$ are cells.
 Moreover, given a fourth cell $D:\cell{h_3}{v_4}{v_5}{h_5}$,
 horizontal and vertical compositions satisfy the following
 \emph{exchange law} (see Figure~\ref{exchlawfig}):

\[
 (A\cdot C) * (B\cdot D) = (A * B)\cdot(C * D)
\]

\noindent
 Under these rules, cells form both a horizontal category ${\cal D}^*$
 and a vertical category ${\cal D}^{\cdot}$, with identities
 $1_{v}:\cell{id_o}{v}{v}{id_{o'}}$ and
 $1^{h}:\cell{h}{id_o}{id_{o'}}{h}$, respectively, with $1^{h_0*h_1} =
 1^{h_0} * 1^{h_1}$ and $1_{v_0\cdot v_1} = 1_{v_0} \cdot 1_{v_1}$.

\item
 Furthermore, horizontal and vertical identities of identities
 coincide, \ie, $1_{id_o} = 1^{id_o}$ and the cell is simply denoted
 by $1_o$.
\end{itemize}
\end{definition}

\begin{figure}
\begin{center}
$\xymatrix@+1pc{
 {\cdot} \ar[r]^{h_0} \ar[d]_{v_0} \ar@{}[rd]|{A} &
 {\cdot} \ar[r]^{h_2} \ar[d]|{v_1} \ar@{}[rd]|{B} &
 {\cdot} \ar[d]^{v_2} \\
 {\cdot} \ar[r]|{h_1} \ar[d]_{v_3} \ar@{}[rd]|{C} &
 {\cdot} \ar[r]|{h_3} \ar[d]|{v_4} \ar@{}[rd]|{D} &
 {\cdot} \ar[d]^{v_5} \\
 {\cdot} \ar[r]_{h_4} &
 {\cdot} \ar[r]_{h_5} &
 {\cdot} }$
\end{center}
\caption{Exchange law of double categories.}
\protect\label{exchlawfig}
\end{figure}

 We shall use monoidal categories (see \eg, \cite{Mac:CWM} for
 basic definitions) for horizontal and vertical 1-categories.
 As a matter of notation,
 sequential composition and monoidal tensor product on 1-categories are denoted
 by $\_;\_$ and $\_\otimes\_$, respectively. A \emph{monoidal double
 category} is a double category together with an associative
 tensor product $\_\otimes\_$ and a unit element $e$.

 Tile logic gives a computational interpretation of (monoidal) double
 categories, where (see Figure~\ref{atilefig} for terminology):

\begin{itemize}
\item
 the objects represent the (initial/final, input/output) interfaces
 through which system components can be connected;

\item
 the arrows of $\mathcal{H}$ describe (initial/final) configurations,
 sources and targets corresponding to input and output interfaces;

\item
 the arrows of $\mathcal{V}$ are the observations (trigger/effect),
 sources and targets corresponding to initial and final interfaces;

\item
 the cells represent the possible transformations (tiles) that can be
 performed by the system.
\end{itemize}

 Thus, a cell $\cell{h_0}{v_0}{v_1}{h_1}$ says that the state
 $h_0$ can evolve to $h_1$ via an action triggered by $v_0$ and
 with effect $v_1$. The way in which observations and
 configurations of a cell are connected via their interfaces
 expresses the locality of actions, \ie, the places where triggers
 are applied to and effects are produced by.

 A basic distinction concerns whether one is interested in the
 cells or just in their borders. The second alternative has a
 more abstract flavor, in  line with behavioral equivalences, and
 corresponds to the so called \emph{flat tile logic} \cite{Bru:TL}.
 In this paper we shall concentrate on flat tiles only.

 Tile logic gives also the possibility of presenting in a constructive
 way the double category of interest. This is in some sense analogous
 to presenting a term algebra by giving only the signature: A standard
 set of rules tells how to build all the elements starting from the
 basic ones. For tile logic, the basic elements consist of: (i) the
 category $\mathcal{H}$ of configurations; (ii) the category
 $\mathcal{V}$ of observations; and (iii) the set of basic tiles (\ie,
 cells on $\mathcal{H}$ and $\mathcal{V}$). Starting from basic
 tiles, more complex tiles can be constructed by means of horizontal,
 vertical and parallel composition.  Moreover, the horizontal and
 vertical identities are always added and composed together with the
 basic tiles. All this is illustrated by the rules in
 Figure~\ref{comptilefig}, where tiles are seen as logic sequents. As
 explained in the Introduction, each operation has a precise
 computational meaning: horizontal composition coordinates the
 evolution of a context with that of its arguments; parallel
 composition models concurrent activities; vertical composition
 appends steps to computations. For both terms and tiles, the
 operation of building all the elements starting from the basic ones
 can be represented by a universal construction corresponding to a
 left adjoint.

\begin{figure}[t]
\begin{center}
 $\irule{\cell{t_0}{u}{v}{s_0}\ \ \cell{t_1}{v}{w}{s_1}}
        {\cell{t_0;t_1}{u}{w}{s_0;s_1}}$
\hfill
 $\irule{\cell{t}{u_0}{v_0}{s}\ \ \cell{s}{u_1}{v_1}{r}}
        {\cell{t}{u_0;u_1}{v_0;v_1}{r}}$
\hfill
 $\irule{\cell{t_0}{u_0}{v_0}{s_0}\ \ \cell{t_1}{u_1}{v_1}{s_1}}
        {\cell{t_0\otimes t_1}{u_0\otimes u_1}{v_0\otimes v_1}{s_0\otimes s_1}}$
\hfill $\irule{t\from o_0\to o_1\in \mathcal{H}}
        {\cell{t}{o_0}{o_1}{t}}$
\hfill $\irule{u\from o_0\to o_1\in \mathcal{V}}
        {\cell{o_0}{u}{u}{o_1}}$
\end{center}
\caption{Composition and identity rules for tile logic.}
\protect\label{comptilefig}
\end{figure}

\begin{definition}[Tile system]
 A \emph{tile system} is a tuple $\mathcal{R} =
 (\mathcal{H},\mathcal{V},N,R)$ where $\mathcal{H}$ and
 $\mathcal{V}$ are monoidal categories with the same set of
 objects $\mathbf{O}_{\mathcal{H}} = \mathbf{O}_{\mathcal{V}}$,
 $N$ is the set of rule names and $R\from N \to
 \mathbf{A}_{\mathcal{H}} \times \mathbf{A}_{\mathcal{V}} \times
 \mathbf{A}_{\mathcal{V}} \times \mathbf{A}_{\mathcal{H}}$ is a
 function such that for all $\alpha\in N$, if $R(\alpha)=\langle
 t,u,v,s\rangle$ then $t\from o_0\to o_1$, $u\from o_0\to o_2$, $v\from
 o_1\to o_3$, and $s\from o_2\to o_3$ for suitable objects $o_0$, $o_1$, $o_2$
 and $o_3$ (see Figure~\ref{gentilefig}).  We will denote such rule
 by writing $\alpha\from \cell{t}{u}{v}{s}$.
\end{definition}

\begin{figure}[t]
\begin{center}
$\xymatrix@R-1pc@C+1pc{
 {o_0} \ar[r]^{t} \ar[d]_{u} \ar@{}[rd]|{\alpha} &
 {o_1} \ar[d]^{v} \\
 {o_2} \ar[r]_{s} &
 {o_3} }$
\end{center}
\caption{A generic tile $\alpha$.}
\protect\label{gentilefig}
\end{figure}

 Depending on the chosen tile format, $\mathcal{H}$ and
 $\mathcal{V}$ can be specialized (\eg, to cartesian categories)
 and suitable \emph{auxiliary tiles} are added and composed with
 basic tiles and identities in all the possible ways. The set of
 resulting sequents (\emph{flat tiles}) define the \emph{flat
 tile logic} associated to $\mathcal{R}$. We say that
 $\cell{t}{u}{v}{s}$ is \emph{entailed} by the logic, written
 $\mathcal{R}\vdash\cell{t}{u}{v}{s}$, if the sequent
 $\cell{t}{u}{v}{s}$ can be expressed as the composition of basic
 and auxiliary tiles. Flat tiles form the cells of a suitable
 double category, which is freely generated by the tile system.

 Being interested in tile systems where configurations and
 observations are freely generated by suitable horizontal and
 vertical signatures, in what follows we shall present tile systems as
 tuples of the form $\mathcal{R}=(\Sigma,\Lambda,N,R)$. In particular,
 we shall employ categories of substitutions on $\Sigma$ and $\Lambda$
 as horizontal and vertical 1-categories. In the literature several
 tile formats have been considered
 \cite{GM:TM,FM:TFLMS,BMM:ETS,BM:CCDC,BFMM:BC}. They are all based on
 the idea of having as underlying categories of configurations and
 effects two categories that are freely generated starting from
 suitable (hyper)signatures whose operators model the basic components
 and observations, respectively.
 Varying the algebraic structure of configurations and observations,
 tiles can model many different aspects of dynamic systems,
 ranging \eg
 from synchronization of Petri net transitions \cite{BM:ZSNCCI}, to causal
 dependencies for located calculi and finitely branching approaches
 for name-passing calculi \cite{FM:TFLMS}, to actor systems
 \cite{MT:APA}, names abstraction and creation and higher order
 structures \cite{BM:CCDC}.
 A comparison between the
 various formats is out of the scope of this presentation and can be
 found in \cite{BFMM:BC}.

 Ordinary trace semantics and bisimilarity semantics can be
 extended to tiles by considering the transition system whose
 states are (possibly open) configurations and whose transitions
 are the entailed tile sequents: a tile $\cell{t}{u}{v}{s}$
 defines a transition from $t$ to $s$ with label $(u,v)$. An
 interesting question concerns suitable conditions under which
 such abstract equivalences yield congruences (\wrt\ the
 operations of the underlying horizontal structure). \emph{Tile
 decomposition} is one such condition that has a completely
 abstract formulation applicable to all tile systems.

\begin{definition}
  A tile system $\mathcal{R} = (\mathcal{H},\mathcal{V},N,R)$
  enjoys the \emph{decomposition property} if for all arrows
  $t \in \mathcal{H}$ and for all sequents
  $\cell{t}{u}{v}{s}$ entailed by~$\mathcal{R}$, then:
  (1)
  if $t = t_1;t_2$ then $\exists w\in\mathcal{V}$,
  $s_1,s_2\in\mathcal{H}$ such that $\mathcal{R}\vdash
  \cell{t_1}{u}{w}{s_1}$, $\mathcal{R}\vdash
  \cell{t_2}{w}{v}{s_2}$ and $s=s_1;s_2$;
  (2) if $t = t_1\otimes t_2$ then
  $\exists u_1,u_2,v_1,v_2\in\mathcal{V}$, $s_1,s_2\in\mathcal{H}$ such
  that $\mathcal{R}\vdash \cell{t_1}{u_1}{v_1}{s_1}$,
  $\mathcal{R}\vdash \cell{t_2}{u_2}{v_2}{s_2}$, $u=u_1\otimes
  u_2$, $v=v_1\otimes v_2$ and $s=s_1\otimes s_2$.
\end{definition}

 Condition (1) is called \emph{sequential decomposition} and condition
 (2) is called \emph{parallel decomposition}.  The decomposition property
 characterizes compositionality: It amounts to saying that if a system
 $t$ can undergo a transition $\alpha$, then for every subsystem $t_1$
 of $t$ there exists some transition $\alpha'$, such that $\alpha$ can
 be obtained by composing $\alpha'$ with a transition of the rest.

\begin{proposition}[cf.~\cite{GM:TM}]\label{decascongprop}
  If $\mathcal{R}$ enjoys the decomposition property, then tile
  bisimilarity (and also tile trace equivalence) are congruences.
\end{proposition}

 When only instantiation/contextualization are considered as
 meaningful operations of the system, then sequential decomposition is
 enough for guaranteeing the congruence of tile bisimilarity and tile
 trace equivalence \wrt\ these closure operations.

\subsection{Algebraic theories}\label{ATsec}

 An alternative presentation of the category of substitutions
 discussed in Section~\ref{Nsec} can be obtained resorting to
 \emph{algebraic theories} \cite{Law:FSAT}.

\begin{remark}
 For simplicity we illustrate here the constructions for one-sorted
 signatures. This can be extended to many sorted signatures by
 considering the free strict monoid on the set of sorts (\eg, strings
 of sorts) in place of underlined natural numbers.
\end{remark}

\begin{definition}[Algebraic theory]
 The free algebraic theory associated to a signature $\Sigma$ is the
 category $\textbf{Th}[\Sigma]$ defined below:
\begin{itemize}
\item
 its objects are `underlined' natural numbers;
\item
 the arrows from $\underline{m}$ to $\underline{n}$ are $n$-tuples of
 terms in the free $\Sigma$-algebra with (at most) $m$ canonical
 variables, and composition of arrows is term substitution. The arrows
 of $\textbf{Th}[\Sigma]$ are generated from $\Sigma$ by the inference
 rules in Figure~\ref{ThSigmafig}, modulo the axioms in
 Table~\ref{ThSigmatab}.
\end{itemize}
\end{definition}

 The category $\textbf{Th}[\Sigma]$ is isomorphic to the
 category of finite substitutions on $\Sigma$ (with canonical sets of
 variables), and the arrows from $\underline{0}$ to
 $\underline{1}$ are in bijective correspondence with the closed terms
 over $\Sigma$.

 An object $\underline{n}$ (interface) can be thought of as
 representing the $n$ (ordered) canonical variables
 $x_1,\ldots,x_n$. This allows us to denote
 $[\sbtn{t_1}{x_1},\ldots,\sbtn{t_n}{x_n}]$ just by the tuple $\langle
 t_1,\ldots,t_n\rangle$, since a standard naming of substituted
 variables can be assumed. We omit angle brackets if no confusion can
 arise.

\begin{remark}
 To avoid confusion, it must be clear that the canonical variables are
 just placeholders, \ie, their scope is only local. For example in
 $[\sbtn{f(x_1)}{x_1}]$ the two $x_1$ are different, while in
 $[\sbtn{f(x_1)}{x_1},\sbtn{g(x_1)}{x_2}]$ only the two occurrences of
 $x_1$ in $f(x_1)$ and $g(x_1)$ refer to the same placeholder. Note that
 $[\sbtn{f(x_1)}{x_1},\sbtn{g(x_2)}{x_1}]$ is inconsistent (because
 $x_1$ is assigned twice) and in fact cannot be expressed in the
 language.
\end{remark}

 The rule $\mathtt{op}$ defines basic substitutions
 $[\sbtn{f(x_1,\ldots,x_n)}{x_1}] = f(x_1,\ldots,x_n)$ for all
 $f\in\Sigma_n$.  The rule $\mathtt{id}$ yields identity substitutions
 $\langle x_1,\ldots,x_n\rangle$. The rule $\mathtt{seq}$ represents
 application of $\alpha$ to $\beta$. The rule $\mathtt{mon}$ composes
 substitutions in parallel (in $\alpha\otimes\beta$, $\alpha$ goes
 from $x_1,\ldots,x_n$ to $x_1,\ldots,x_m$, while $\beta$ goes from
 $x_{n+1},\ldots,x_{n+k}$ to $x_{m+1},\ldots,x_{m+l}$).  Three
 `auxiliary' operators (\ie, not dependent on $\Sigma$) are introduced
 that recover the cartesian structure (rules $\mathtt{sym}$,
 $\mathtt{dup}$ and $\mathtt{dis}$). The \emph{symmetry}
 $\gamma_{\underline{n},\underline{m}}$ is the permutation $\langle
 x_{n+1},\ldots,x_{n+m}, x_1,\ldots,x_n\rangle$. The \emph{duplicator}
 $\nabla_{\underline{n}} = \langle x_1,\ldots,x_n,x_1,\ldots,x_n
 \rangle$ introduces sharing and hence nonlinear substitutions.  The
 \emph{discharger} $!_{\underline{n}}$ is the empty substitution on
 $x_1,\ldots,x_n$, recovering cartesian projections.

\begin{figure}[t]
\begin{center}
$\mathtt{op}\ \
  \irule{f\in\Sigma_n}
        {f \from \underline{n} \to \underline{1}}
\hfill
  \mathtt{id}\ \
  \irule{n\in\nat}
        {id_{\underline{n}}\from \underline{n} \to \underline{n}}
\hfill
  \mathtt{seq}\ \
  \irule{\alpha \from \underline{n} \to \underline{m}\ \ \
         \beta \from \underline{m} \to \underline{k}}
        {\alpha;\beta \from \underline{n} \to \underline{k}}
\hfill
  \mathtt{mon}\ \
  \irule{\alpha \from \underline{n} \to \underline{m}\ \ \
         \beta \from \underline{k} \to \underline{l}}
        {\alpha\otimes\beta \from \underline{n+k} \to \underline{m+l}}$
\end{center}
\begin{center}
$\mathtt{sym}\ \
  \irule{n,m\in\nat}
        {\gamma_{\underline{n},\underline{m}}\from \underline{n+m} \to
\underline{m+n}}
\hfill
  \mathtt{dup}\ \
  \irule{n\in\nat}
        {\nabla_{\underline{n}}\from \underline{n} \to \underline{n+n}}
\hfill
  \mathtt{dis}\ \
  \irule{n\in\nat}
        {!_{\underline{n}}\from \underline{n} \to \underline{0}}$
\end{center}
\caption{The inference rules for the generation of $\textbf{Th}[\Sigma]$.}
\protect\label{ThSigmafig}
\end{figure}

 Let us briefly comment on the axiomatization in
 Table~\ref{ThSigmatab}. The first two rows say that
 $\textbf{Th}[\Sigma]$ is a strict monoidal category, with tensor
 product $\otimes$ and neutral element $id_{\underline{0}}$. The third
 row and the naturality axiom for symmetries (first axiom of the last
 row) say that $\textbf{Th}[\Sigma]$ is also symmetric. In particular,
 the axioms in the third row state the coherence of symmetries
 $\gamma_{\underline{n},\underline{m}}$, namely that all the
 equivalent ways of swapping the first $n$ variables with the
 following $m$ variables built out of the basic symmetry
 $\gamma_{\underline{1},\underline{1}}$ (that swaps two adjacent
 variables) are identified. The axioms in the fourth row accomplish a
 similar task for duplicators, and those in the fifth row for
 dischargers. The naturality of duplicators and dischargers (second
 and third axioms of the last row) makes $\textbf{Th}[\Sigma]$
 cartesian.

\begin{table}[t]
\begin{center}
\caption{Axiomatization of $\textbf{Th}[\Sigma]$.}
\protect\label{ThSigmatab}
\footnotesize
\begin{tabular}{llcr}
\hline
\hline
  category &
  $\alpha;(\beta;\delta) = (\alpha;\beta);\delta$ & &
  $\alpha;id_{\underline{m}} = \alpha = id_{\underline{n}};\alpha$ \\
\\
  tensor &
  $(\alpha;\alpha')\otimes(\beta;\beta') =
   (\alpha\otimes\beta);(\alpha'\otimes\beta')$ & &
  $id_{\underline{n+m}} = id_{\underline{n}}\otimes id_{\underline{m}}$ \\
  product &
  $\alpha\otimes(\beta\otimes\delta) = (\alpha\otimes\beta)\otimes\delta$ & &
  $\alpha\otimes id_{\underline{0}} = \alpha =
   id_{\underline{0}}\otimes\alpha$ \\
\\
  symmetries &
  $\gamma_{\underline{n},\underline{m+k}} =
    (\gamma_{\underline{n},\underline{m}}\otimes
    id_{\underline{k}});(id_{\underline{m}}\otimes
    \gamma_{\underline{n},\underline{k}})$ &
  $\gamma_{\underline{n},\underline{0}} = id_{\underline{n}}$ &
  $\gamma_{\underline{n},\underline{m}};
   \gamma_{\underline{m},\underline{n}} = id_{\underline{n+m}}$ \\
\\
  duplicators &
  $\nabla_{\underline{n+m}} = (\nabla_{\underline{n}}\otimes
   \nabla_{\underline{m}});(id_{\underline{n}}\otimes
   \gamma_{\underline{n},\underline{m}} \otimes id_{\underline{m}})$ & &
  $\nabla_{\underline{0}} = id_{\underline{0}}$ \\
  & $\nabla_{\underline{n}};(id_{\underline{n}}\otimes\nabla_{\underline{n}})
    = \nabla_{\underline{n}};(\nabla_{\underline{n}}\otimes
    id_{\underline{n}})$ & &
  $\nabla_{\underline{n}};\gamma_{\underline{n},\underline{n}} =
\nabla_{\underline{n}}$ \\
\\
  discharger &
  $!_{\underline{n+m}} = !_{\underline{n}} \otimes !_{\underline{m}}$ &
  $!_{\underline{0}} = id_{\underline{0}}$ &
  $\nabla_{\underline{n}};(id_{\underline{n}}\otimes
   !_{\underline{n}}) = id_{\underline{n}}$ \\
\\
  naturality &
  $(\alpha\otimes\beta);\gamma_{\underline{m},\underline{l}} =
   \gamma_{\underline{n},\underline{k}};(\beta\otimes\alpha)$ &
  $\alpha;\nabla_{\underline{m}} =
   \nabla_{\underline{n}};(\alpha\otimes\alpha)$ &
  $\alpha;!_{\underline{m}} = !_{\underline{n}}$ \\
\hline
\hline
\end{tabular}
\end{center}
\end{table}

 This presentation shows that all the auxiliary structure can be
 generated by composing together three basic constructors
 ($\gamma_{\underline{1},\underline{1}}$, $\nabla_{\underline{1}}$ and
 $!_{\underline{1}}$), \ie, it admits a finitary specification.
 Moreover, we think that this construction nicely separates the
 syntactic structure of the signature from the additional auxiliary
 structure common to all cartesian models.

 The axiomatization of $\textbf{Th}[\Sigma]$ has been exploited in
 \cite{BFMM:BC} for defining a
 taxonomy of tile formats as certain axioms or operators are omitted
 from the configuration and observation categories. In particular the
 auxiliary tiles needed in all such formats can be characterized as
 the bidimensional counterparts of symmetries, duplicators and
 dischargers. For example, let us mention that the auxiliary tiles of
 \emph{term tile logic} \cite{BMM:PTTL} (where the categories of
 configurations and observations are freely generated cartesian
 categories $\textbf{Th}[\Sigma]$ and $\textbf{Th}[\Lambda]$) are the
 commuting squares of the category $\textbf{Th}[\emptyset]$ generated
 by the empty signature.

\section{Resolution via pullbacks}\label{RVPsec}

 As we have briefly recalled in the Introduction, the construction
 of the mgu has a clear mathematical meaning: It can be
 formulated in the terminology of category theory as a well-known
 universal construction called pullback (taken in a suitable category).

 Universal constructions play a fundamental role in category
 theory, as they express the best way to accomplish a certain
 task. They usually involve a diagram that imposes certain
 constraints on the construction and then require the existence
 and uniqueness in the category of certain arrows satisfying such
 constraints, \ie, representing a possible solution to the
 problem. Among these solutions, one is of course interested in
 the optimal one (if it exists), \eg, the least upper
 bound. Categorically speaking, this is
 achieved by taking the solution that uniquely factorizes all the
 other solutions. Note that since many such optimal solutions can
 exist, any of them is completely equivalent to all the others
 (they are indeed pairwise isomorphic). Universal constructions
 allow one to recast ordinary set-theoretic constructions (\eg,
 cartesian product, disjoint sum) in a more general, abstract
 formulation that can serve as a uniform guide for catching
 analogies and pursuing comparisons between different frameworks.

\begin{definition}[Pullback]
 Given a category $\mathcal{C}$ and two arrows $h\from o_0 \to o_2$
 and $g\from o_1 \to o_2$ in $\mathcal{C}$, the \emph{pullback} of $h$ and $g$ in
 $\mathcal{C}$ is an object $o$ together with two projections
 $p_0 \from o \to o_0$ and $p_1 \from o \to o_1$ such that
 \begin{enumerate}
 \item $p_0;h = p_1;g$, and
 \item for any object $o'$ and arrows $q_0 \from o' \to o_0$ and $q_1 \from o' \to
 o_1$ such that $q_0;h = q_1;g$, then there must exist a unique arrow
 $q\from o'\to o$ such that $q;p_0 = q_0$ and $q;p_1 = q_1$.
 \end{enumerate}
\end{definition}

 The two arrows $h$ and $g$ encode the instance of the problem,
 posing constraints on the admissible solutions. The first condition
 says that $o$, $p_0$ and $p_1$ yield a solution (called a \emph{cone}
 in category theory). The second condition states that $o$, $p_0$ and
 $p_1$ form the best solution among those contained in $\mathcal{C}$.
 The commuting diagram in Figure~\ref{pullbackfig} illustrates the
 definition (as usual in category theory, universal arrows are dotted).

\begin{figure}[t]
\begin{center}
$\xymatrix{
 {o'} \ar@{.>}[rd]^{q} \ar@/^/[rrd]^{q_0} \ar@/_/[rdd]_{q_1} \\
 & {o} \ar[r]^{p_0} \ar[d]_{p_1} &
 {o_0} \ar[d]^{h} \\
 & {o_1} \ar[r]_{g} &
 {o_2} }$
\end{center}
\caption{The pullback of $h$ and $g$.} \protect\label{pullbackfig}
\end{figure}

\begin{example}[Pullbacks in $\Set$]
 The category $\Set$ has sets as objects and functions as arrows.
 Given $h\from X \to Z$ and $g\from Y \to Z$, then their pullback is
 the set $U = \{(x,y)\in X\times Y \mid h(x)=g(y)\}$ with the
 obvious projections on the first and second components of each
 pair in $U$.
\end{example}

 The category we are interested in is the category of substitutions on
 the signature $\Sigma$. It is well known that the mgu of a set of
 equations is an equalizer in the category of substitutions (see \eg,
 \cite{BR:CUA,Gog:WIU}, though there the authors work with the opposite
 category $\mathbf{Th}[\Sigma]^{\mathrm{op}}$ of
 $\mathbf{Th}[\Sigma]$, and therefore the mgu's are given by
 coequalizers).

\begin{definition}[Equalizer]
 Given a category $\mathcal{C}$ and two arrows $h\from o_1 \to o_2$
 and $g\from o_1 \to o_2$, the \emph{equalizer} of $h$ and $g$ in
 $\mathcal{C}$ is an object $o$ together with a projection
 $p \from o \to o_1$ such that
 \begin{enumerate}
 \item $p;h = p;g$, and
 \item for any object $o'$ and arrow $q \from o' \to o_1$
 such that $q;h = q;g$, then there must exist a unique arrow
 $q'\from o'\to o$ such that $q';p = q$.
 \end{enumerate}
\end{definition}

\begin{figure}[t]
\begin{center}
\begin{tabular}{ccc}
$\vcenter{\xymatrix{
 {o} \ar[r]^{p} &
 {o_1} \ar@/^/[r]^{h} \ar@/_/[r]_{g} &
 {o_2} \\
 {o'} \ar@{.>}[u]^{q'} \ar[ru]_{q} }}$ & &
$\vcenter{\xymatrix{
 {o} \ar@{.>}[rd]^{r} \ar@/^/[rrd]^{p} \ar@/_/[rdd]_{p} \\
 & {o'_1} \ar[r]^{p_1} \ar[d]_{p'_1} &
 {o_1} \ar[d]^{h} \\
 & {o_1} \ar[r]_{g} &
 {o_2} }}$ \\
 (a) & & (b)
\end{tabular}
\end{center}
\caption{The equalizer (a)  and the pullback of $h$ and $g$
 in the same homset (b).}
\protect\label{equalizerfig}
\end{figure}

 The diagram summarizing the equalizer construction is given in
 Figure~\ref{equalizerfig}(a).

\begin{example}[Equalizers in $\Set$]
 Given $h\from X \to Z$ and $g\from X \to Z$, then their equalizer is
 the subset $U = \{x\in X \mid h(x)=g(x)\}$ of $X$ with the obvious
 inclusion $U\hookrightarrow X$ as projection.
\end{example}

 Note that, in general, for $h,g\from o_1 \to o_2$ the pullback
 of $h$ and $g$ is not
 isomorphic to their equalizer. Moreover, when both exist, the
 cone $(o,p,p)$ (obtained by taking twice the projection of the
 equalizer) uniquely factorizes through the pullback
 $(o'_1,p_1,p'_1)$ (see Figure~\ref{equalizerfig}(b)).

 For a given set of equations $\{t_1 = s_1, t_2 = s_2, \ldots, t_n=
 s_n\}$, we can consider the substitutions $\sigma =
 [\sbtn{t_1}{z_1},\sbtn{t_2}{z_2},\cdots,\sbtn{t_n}{z_n}]$ and $\sigma' =
 [\sbtn{s_1}{z_1},\sbtn{s_2}{z_2},\cdots,\sbtn{s_n}{z_n}]$, where the
 $z_i$'s are fresh variables not appearing in the $t_i$'s and
 $s_i$'s. The substitutions $\sigma$ and $\sigma'$ can be seen as
 arrows going from the set of variables appearing in the $t_i$'s and
 $s_i$'s to the set $Z = \{z_1,z_2,\ldots,z_n\}$.  To see how the
 definition of equalizer matches that of mgu, just observe that (1)
 it requires the existence of a substitution $\theta$ such that
 $\theta;\sigma = \theta;\sigma'$ and (2) the fact that $\theta$
 is the most general such substitution corresponds to the universal
 property of equalizers.

 However, in the case of logic programming, we are not really
 interested in finding the mgu of a generic set of equations, because
 we know that the variables in the head of the selected clause have
 been renamed on purpose to be different from those in the selected
 goal, \ie, they are fresh. Thus, we want to find the mgu of a set of
 equations $\{t_1 = s_1, t_2 = s_2, \ldots, t_n= s_n\}$ such that the
 variables appearing in $t_i$ and $s_j$ are disjoint for $i,j\in
 [1,n]$. Then, we can consider the substitutions $\sigma_* =
 [\sbtn{t_1}{z_1},\sbtn{t_2}{z_2},\cdots,\sbtn{t_n}{z_n}]$ and $\sigma'_*
 = [\sbtn{s_1}{z_1},\sbtn{s_2}{z_2},\cdots,\sbtn{s_n}{z_n}]$, where the
 $z_i$'s are fresh variables not appearing in the $t_i$'s and
 $s_i$'s. If we denote by $X$ the set of variables appearing in the
 $t_i$'s, by $Y$ the set of variables used in the $s_i$'s, and by $Z$
 the set $\{z_1,z_2,\ldots,z_n\}$, then we can write $\sigma_*\from X \to
 Z$ and $\sigma'_*\from Y\to Z$. Their pullback (when it exists) is
 thus given by a pair of substitutions $\psi_*\from U_*\to X$ and
 $\psi'_*\from U_*\to Y$ such that
\begin{itemize}
 \item $\psi_*;\sigma_* = \psi'_*;\sigma'_*$, and
 \item for any substitutions $\rho \from V \to X$ and $\rho' \from V
       \to Y$ such that $\rho;\sigma_* = \rho';\sigma'_*$, then there
       must exist a unique substitution $\phi \from V\to U_*$ such
       that $\phi;\psi_* = \rho$ and $\phi;\psi'_* = \rho'$.
\end{itemize}

 Since the fact that the notion of pullback of $\sigma_*$ and
 $\sigma'_*$ coincides with the notion of equalizer of $\sigma$ and
 $\sigma'$ is not completely straightforward, we illustrate below such
 a correspondence.

\paragraph{From equalizers to pullbacks.}

 Consider the arrows $\sigma\from X\cup Y \to Z$ and
 $\sigma'\from X\cup Y \to Z$ that are defined exactly as $\sigma_*$
 and $\sigma'_*$ but have different domains. Then, we know that their
 mgu is the equalizer $\theta\from U\to X\cup Y$ discussed
 above. Since $\theta$ is a substitution and since $X=\{x_1,\ldots,x_k\}$
 and $Y=\{y_1,\ldots,y_h\}$ are disjoint, then $\theta$ must have
 the form

\begin{center}
 $[\sbtn{r_1}{x_1}, \cdots, \sbtn{r_k}{x_k},
  \sbtn{r'_1}{y_1}, \cdots, \sbtn{r'_k}{y_h}]$.
\end{center}

 Then, $\theta_X=[\sbtn{r_1}{x_1},\cdots,\sbtn{r_k}{x_k}]\from U \to X$
 and $\theta_Y=[\sbtn{r'_1}{y_1},\cdots,\sbtn{r'_k}{y_h}]\from U\to Y$
 satisfy $\theta_X;\sigma_* = \theta_Y;\sigma'_*$. We want to show
 that $U$, $\theta_X$ and $\theta_Y$ define a pullback of $\sigma_*$
 and $\sigma'_*$. In fact, suppose that there exist $V$ with $\rho
 \from V \to X$ and $\rho' \from V \to Y$ such that $\rho;\sigma_* =
 \rho';\sigma'_*$, then since $X$ and $Y$ are disjoint, $\rho$ and
 $\rho'$ can be combined together in a substitution $\rho_*\from V \to
 X\cup Y$ such that $\rho_*;\sigma = \rho_*;\sigma'$. By definition of
 equalizer, then there exists a unique arrow $\phi \from V \to U$ such
 that $\phi;\theta = \rho_*$. But the last condition is equivalent to
 imposing that $\phi;\theta_X = \rho$ and $\phi;\theta_Y = \rho'$
 concluding the proof. All this is illustrated in
 Figure~\ref{firstpartfig}.

\begin{figure}[t]
\begin{center}
\begin{tabular}{ccc}
$\vcenter{\xymatrix{
 {U} \ar[r]^{\theta} &
 {X\cup Y} \ar@/^/[r]^{\sigma} \ar@/_/[r]_{\sigma'} &
 {Z} \\
 {V} \ar@{.>}[u]^{\phi} \ar[ru]_{\rho_*} } }$ & &
$\vcenter{\xymatrix{
 & & {X} \ar[rd]^{\sigma_*} \\
 {V} \ar@/^/[rru]^{\rho} \ar@/_/[rrd]_{\rho'} \ar@{.>}[r]^{\phi} &
 {U} \ar[ru]^{\theta_X} \ar[rd]_{\theta_Y} & &
 {Z} \\
 & & {Y} \ar[ru]_{\sigma'_*} }}$
\end{tabular}
\end{center}
\caption{From equalizer to pullback.}
\protect\label{firstpartfig}
\end{figure}


\paragraph{From pullbacks to equalizers.}

 It remains to show that to each pullback $(U',\psi_X,\psi_Y)$ of
 $\sigma_*$ and $\sigma'_*$ there corresponds an mgu (\ie, an
 equalizer) of $\sigma$ and $\sigma'$. By arguments similar to those
 employed above, it is evident that $\psi_X$ and $\psi_Y$ can be
 merged to define a substitution $\psi_*\from U'\to X\cup Y$ such that
 $\psi_*;\sigma = \psi_*;\sigma'$. Then, we must show that this
 candidate is indeed an equalizer. Thus, we assume the existence of
 $V$ and $\rho_*\from V\to X\cup Y$ such that $\rho_*;\sigma =
 \rho_*;\sigma'$. As before, we can decompose $\rho_*$ into
 $\rho_X\from V\to X$ and $\rho_Y\from V\to Y$ with $\rho_X;\sigma_* =
 \rho_Y;\sigma'_*$. By definition of pullback, then there exists a
 unique arrow $\phi_*\from V\to U'$ such that $\phi_*;\psi_X = \rho_X$
 and $\phi_*;\psi_Y = \rho_Y$, and the last two conditions are
 equivalent to the constraint $\phi_*;\psi_* = \rho_*$, concluding the
 proof.  All this is illustrated in Figure~\ref{secondpartfig}.

\begin{figure}[t]
\begin{center}
\begin{tabular}{ccc}
$\vcenter{\xymatrix{
 & & {X} \ar[rd]^{\sigma_*} \\
 {V} \ar@/^/[rru]^{\rho_X} \ar@/_/[rrd]_{\rho_Y} \ar@{.>}[r]^{\phi_*} &
 {U'} \ar[ru]^{\psi_X} \ar[rd]_{\psi_Y} & &
 {Z} \\
 & & {Y} \ar[ru]_{\sigma'_*} }}$ & &
$\vcenter{\xymatrix{
 {U'} \ar[r]^{\psi_*} &
 {X\cup Y} \ar@/^/[r]^{\sigma} \ar@/_/[r]_{\sigma'} &
 {Z} \\
 {V} \ar@{.>}[u]^{\phi_*} \ar[ru]_{\rho_*} } }$
\end{tabular}
\end{center}
\caption{From pullback to equalizer.}
\protect\label{secondpartfig}
\end{figure}

\paragraph{}

 Of course, it might well be the case that no such arrows $\psi$
 and $\psi'$ exist, \eg, when one tries to solve the sets $\{f(x)
 = f'(y)\}$ or $\{f(x) = x\}$ for unary operation symbols $f$ and
 $f'$.  There can also exist more solutions than one, and this is
 always the case as the names of the variables in $U$ are not
 important at all.

 The different flavors corresponding to the equalizer and the
 pullback views rely on the fact that in the equalizer
 construction we have to work with the full universe $\mathcal{X}$
 of \emph{all} variables, while in the pullback
 construction only the variables of interest for a particular mgu
 creation must be considered. Therefore, the equalizer
 approach is completely centralized, while the pullback
 construction is as much distributed as possible.
 Nevertheless, the result above proves that the two views
 are equivalent.


\section{The double category of pullbacks}\label{DCPsec}

 In this section we show that the construction of pullbacks in the
 category of substitutions can be presented in a modular way, by
 composing together a finite set of basic pullbacks.  We start by
 showing that the pullback squares in a category $\mathcal{C}$ form a
 double category. To see this, let us remind a few classical results.

\begin{proposition}\label{proppbcompdef}
 Given a category $\mathcal{C}$ and three arrows $h\from o_0\to o_3$,
 $g_1\from o_1 \to o_2$ and $g_2\from o_2 \to o_3$, let $(o,p_0,p_2)$
 be the pullback of $h$ and $g_2$, and let $(o',q_0,q_1)$ be the
 pullback of $p_2$ and $g_1$ (see Figure~\ref{pbcompfig}). Then,
 $(o',q_0;p_0,q_1)$ is a pullback of $h$ and $g_1;g_2$.
\end{proposition}

\begin{proposition}
 Given a category $\mathcal{C}$ and three arrows $h\from o_0\to o_3$,
 $g_1\from o_1 \to o_2$ and $g_2\from o_2 \to o_3$, let $(o,p_0,p_2)$ be the
 pullback of $h$ and $g_2$, and let $(o',q_0;p_0,q_1)$ be the pullback
 of $h$ and $g_1;g_2$. Then, $(o',q_0,q_1)$
 is a pullback of $p_2$ and $g_1$.
\end{proposition}

\begin{proposition}
 The pullback of $h\from o_0 \to o_1$ and $id_{o_1}\from o_1\to o_1$
 exists in any category. Moreover, $(o_0,id_{o_0},h)$ is a pullback
 of $h$ and $id_{o_1}$.
\end{proposition}

\begin{definition}[Double category of pullbacks]
 Given a category $\mathcal{C}$, the double category of pullbacks in
 $\mathcal{C}$, denoted by $\mathscr{P}(\mathcal{C})$, is defined as
 follows:
\begin{itemize}
\item
 its objects are the objects of $\mathcal{C}$;
\item
 its horizontal 1-category is $\mathcal{C}$;
\item
 its vertical 1-category is $\mathcal{C}$;
\item
 the cells are the squares $(p_0,p_1,h,g)$ (see
 Figure~\ref{pbsqfig}) such that $p_0$ and $p_1$ define a pullback
 of $h$ and $g$;
\item
 given two cells $(q,q',p',g_1)$ and $(p,p',h,g_2)$ their
 horizontal composition is the cell $(q;p,q',h,g_1;g_2)$;
\item
 given two cells $(q,q',h_1,p)$ and $(p,p',h_2,g)$ their
 vertical composition is the cell $(q,q';p',h_1;h_2,g)$.
\end{itemize}
\end{definition}

\begin{figure}
\begin{center}
$\xymatrix{
 {o'} \ar[r]^{q_0} \ar[d]_{q_1} &
 {o} \ar[r]^{p_0} \ar[d]|{p_2} &
 {o_0} \ar[d]^{h} \\
 {o_1} \ar[r]_{g_1} &
 {o_2} \ar[r]_{g_2} &
 {o_3}
}$
\end{center}
\caption{Composition of pullbacks.}
\protect\label{pbcompfig}
\end{figure}

\begin{figure}[t]
\begin{center}
$\xymatrix{
 {o} \ar[r]^{p_0} \ar[d]_{p_1} &
 {o_0} \ar[d]^{h} \\
 {o_1} \ar[r]_{g} &
 {o_2} }$
\end{center}
\caption{Pullback square as double cell.}
\protect\label{pbsqfig}
\end{figure}

 To see that $\mathscr{P}(\mathcal{C})$ is indeed a double category,
 observe that both horizontal and vertical compositions of
 cells return pullback squares (Proposition~\ref{proppbcompdef}).
 Moreover, the trivial pullback squares $(id_{o_0},p,p,id_{o_1})$ and
 $(p,id_{o_0},id_{o_1},p)$ behave as identities \wrt\ the horizontal and
 vertical composition, respectively. The exchange law of double
 categories holds trivially, as the cells are completely identified by
 their borders.

 For the arguments presented in the previous section, it follows that
 pullbacks are a fundamental ingredient in the operational semantics,
 as they provide a characterization of the mgu construction, which
 clearly separates the goal dimension (horizontal) from the
 resolution mechanism (the vertical dimension) focusing on their
 interaction (the substitutions yielding the pullback).

 However, dealing with all this machinery at the computational level
 is too heavy, as there are infinitely many pullbacks. Therefore, a
 finitary presentation of $\mathscr{P}(\mathcal{C})$ is a main issue.

\subsection{Finitary presentation of pullbacks}\label{FPPsec}

 Our first contribution consists of recovering in a finitary way the
 double category $\mathscr{P}(\textbf{Th}[\Sigma])$. We start by
 focusing on the small set of commuting squares depicted in
 Figure~\ref{basicpbkfig}. We want to show that any pullback can then
 be obtained by composing these basic squares (and horizontal and
 vertical identity pullbacks), \ie\ that the basic squares
 in Figure~\ref{basicpbkfig} form a basis for the
 generation of arbitrary pullbacks.

\begin{figure}[t]
\begin{center}
$\vcenter{\xymatrix{
 {\underline{1}} \ar@{}[rd]|{R_f} &
 {\underline{n}} \ar[l]_{f} \\
 {\underline{n}} \ar[u]^{f} &
 {\underline{n}} \ar[l]^{id_{\underline{n}}} \ar[u]_{id_{\underline{n}}} }}$
\hfill
 $\vcenter{\xymatrix{
 {\underline{2}} \ar@{}[rdd]|{D_f} &
 {\underline{n+1}} \ar[l]_{f\otimes id_{\underline{1}}} \\
 & {\underline{2n}} \ar[u]_{id_{\underline{n}}\otimes f} \\
 {\underline{1}} \ar[uu]^{\nabla_{\underline{1}}} &
 {\underline{n}} \ar[l]^{f} \ar[u]_{\nabla_{\underline{n}}} }}$
\hfill $\vcenter{\xymatrix{
 {\underline{2}} \ar@{}[rrd]|{\hat{D}_f} & &
 {\underline{1}} \ar[ll]_{\nabla_{\underline{1}}} \\
 {\underline{n+1}} \ar[u]^{f\otimes id_{\underline{1}}} &
 {\underline{2n}} \ar[l]^{id_{\underline{n}} \otimes f} &
 {\underline{n}} \ar[l]^{\nabla_{\underline{n}}} \ar[u]_{f} }}$
\hfill (for all $f\in\Sigma^n$)
\end{center}
\begin{center}
$\vcenter{\xymatrix{
 {\underline{2}} \ar@{}[rd]|{R_\nabla} &
 {\underline{1}} \ar[l]_{\nabla_{\underline{1}}} \\
 {\underline{1}} \ar[u]^{\nabla_{\underline{1}}} &
 {\underline{1}} \ar[l]^{id_{\underline{1}}} \ar[u]_{id_{\underline{1}}} }} $
\hfill $\vcenter{\xymatrix{
 {\underline{2}} \ar@{}[rd]|{R_\gamma} &
 {\underline{2}} \ar[l]_{\gamma_{\underline{1},\underline{1}}} \\
 {\underline{2}} \ar[u]^{\gamma_{\underline{1},\underline{1}}} &
 {\underline{2}} \ar[l]^{id_{\underline{2}}} \ar[u]_{id_{\underline{2}}} }}$
\hfill $\vcenter{\xymatrix{
 {\underline{3}} \ar@{}[rd]|{D_\nabla} &
 {\underline{2}} \ar[l]_{\nabla_{\underline{1}}\otimes id_{\underline{1}}} \\
 {\underline{2}} \ar[u]^{id_{\underline{1}}\otimes \nabla_{\underline{1}}} &
 {\underline{1}} \ar[l]^{\nabla_{\underline{1}}}
                 \ar[u]_{\nabla_{\underline{1}}} }}$
\end{center}
\caption{The basic pullbacks.}
\protect\label{basicpbkfig}
\end{figure}

 There are a few points for which some explanation is worth. First of
 all, note that we have depicted the pullback cells with the direction
 of the arrows reversed with respect to the usual presentation. The
 reason for this will become much clearer in Section~\ref{TSLPsec},
 where we will show that this representation matches the intuitive
 direction of computation flow (from up to down) and also of
 internal contextualizations, which now compose to the right of the current state.
 From the point of view of the notation this is not problematic in tile logic,
 as we can assume to work with opposite categories of configuration
 and observations. As a matter of notation, the tiles in
 Figure~\ref{basicpbkfig} can be written as the sequents
 \begin{itemize}
 \item
 $R_f\from
 \cell{f}{f}{id_{\underline{n}}}{id_{\underline{n}}}$,
 \item
 $D_f\from
 \cell{f\otimes id_{\underline{1}}}{\nabla_{\underline{1}}}
      {\nabla_{\underline{n}};(id_{\underline{n}}\otimes f)}{f}$,
 \item
 $\hat{D}_f\from
 \cell{\nabla_{\underline{1}}}{f\otimes id_{\underline{1}}}
      {f}{\nabla_{\underline{n}};(id_{\underline{n}}\otimes f)}$,
 \item
 $R_\nabla\from
 \cell{\nabla_{\underline{1}}}{\nabla_{\underline{1}}}
      {id_{\underline{1}}}{id_{\underline{1}}}$,
 \item
 $R_\gamma\from
 \cell{\gamma_{\underline{1},\underline{1}}}
      {\gamma_{\underline{1},\underline{1}}}
      {id_{\underline{2}}}{id_{\underline{2}}}$, and
 \item
 $D_\nabla\from
 \cell{\nabla_{\underline{1}} \otimes id_{\underline{1}}}
      {id_{\underline{1}} \otimes \nabla_{\underline{1}}}
      {\nabla_{\underline{1}}}{\nabla_{\underline{1}}}$.
 \end{itemize}

 The second point to notice is that the cells $R_\nabla$, $R_\gamma$, and
 $D_\nabla$ do not depend on $\Sigma$, \ie, they form in some sense
 the intrinsic auxiliary structure of the pullback construction.

\begin{definition}
 We let $\mathcal{B} = \{R_\nabla, R_\gamma, D_\nabla\}$ be
 the \emph{signature-independent pullback basis}, and let
 $\mathcal{B}(f) = \{R_f ,D_f, \hat{D}_f\}$ be the \emph{pullback
 basis for the operator $f$}. Given a signature $\Sigma$,
 we call $\mathcal{B}(\Sigma) = \mathcal{B} \cup
 \bigcup_{f\in\Sigma} \mathcal{B}(f)$ the \emph{pullback
 basis for $\Sigma$}. We say that the cell
 $\cell{s}{u}{v}{t}$ is \emph{generated} by
 $\mathcal{B}(\Sigma)$, if it can be expressed as the
 parallel and sequential composition of cells in
 $\mathcal{B}(\Sigma)$ and identity cells.
\end{definition}

\begin{figure}[t]
\begin{center}
$\vcenter{\xymatrix{
 {\underline{0}} \ar@{}[rd]|{R_!} &
 {\underline{1}} \ar[l]_{!_{\underline{1}}} \\
 {\underline{1}} \ar[u]^{!_{\underline{1}}} &
 {\underline{1}} \ar[l]^{id_{\underline{1}}} \ar[u]_{id_{\underline{1}}} }}$
\hfill $\vcenter{\xymatrix{
 {\underline{3}} \ar@{}[rd]|{\hat{D}_\nabla} &
 {\underline{2}} \ar[l]_{id_{\underline{1}} \otimes \nabla_{\underline{1}}} \\
 {\underline{2}} \ar[u]^{\nabla_{\underline{1}} \otimes id_{\underline{1}}} &
 {\underline{1}} \ar[l]^{\nabla_{\underline{1}}} \ar[u]_{\nabla_{\underline{1}}} }}$
\hfill $\vcenter{\xymatrix{
 {\underline{2}} \ar@{}[rrd]|{\hat{D}'_f} & &
 {\underline{1}} \ar[ll]_{\nabla_{\underline{1}}} \\
 {\underline{1+n}} \ar[u]^{id_{\underline{1}}\otimes f} &
 {\underline{2n}} \ar[l]^{f \otimes id_{\underline{n}}} &
 {\underline{n}} \ar[l]^{\nabla_{\underline{n}}} \ar[u]_{f} }}$
\end{center}
\caption{\textbf{Q}: Are these three basic cells missing?
\textbf{A}:No.}
\protect\label{misstilesfig}
\end{figure}

 There are some cells that one might expect to see
 in Figure~\ref{basicpbkfig} but are instead missing. Trying to
 guess the intuition of the reader, we have listed some of them in
 Figure~\ref{misstilesfig}.

 The first cell we consider is $R_!$. Its absence might be surprising,
 because there are analogous cells for all the other basic
 constructors (operators $f\in\Sigma$, symmetries and duplicators).
 But $R_!$ is not a pullback. In fact the pullback of
 $!_{\underline{1}}$ and $!_{\underline{1}}$ is
 $(\underline{2},id_{\underline{1}} \otimes !_{\underline{1}},
 !_{\underline{1}}\otimes id_{\underline{1}})$, yielding a cell that
 can in fact be obtained by composing in parallel the horizontal and
 vertical identities of $!_{\underline{1}}$ (\ie, by putting
 $\cell{id_{\underline{0}}}
       {!_{\underline{1}}}
       {!_{\underline{1}}}
       {id_{\underline{1}}}$ in parallel with
 $\cell{!_{\underline{1}}}
       {id_{\underline{0}}}
       {id_{\underline{1}}}
       {!_{\underline{1}}}$).


\begin{figure}[t]
\begin{center}
$\xymatrix@C=+2cm{
 {\underline{3}} \ar@{}[rd]|{A_1} &
 {\underline{3}} \ar[l]_{(\gamma_{\underline{1},\underline{1}}\otimes id_{\underline{1}});
                         \gamma_{\underline{2},\underline{1}}}
                 \ar@{}[rd]|{A_2} &
 {\underline{3}} \ar[l]_{\gamma_{\underline{1},\underline{1}}\otimes id_{\underline{1}}}
                 \ar@{}[rrd]|{A_3} &
 {\underline{3}} \ar[l]_{\gamma_{\underline{1},\underline{2}}} &
 {\underline{2}} \ar[l]_{id_{\underline{1}}\otimes \nabla_{\underline{1}}} \\
 {\underline{3}} \ar[u]^{(id_{\underline{1}}\otimes\gamma_{\underline{1},\underline{1}});
                         \gamma_{\underline{1},\underline{2}}}
                 \ar@{}[rd]|{A_4} &
 {\underline{3}} \ar[l]|{id_{\underline{3}}} \ar[u]|{id_{\underline{3}}}
                 \ar@{}[rrdd]|{A_5} &
 {\underline{3}} \ar[l]|{\gamma_{\underline{1},\underline{1}}\otimes id_{\underline{1}}}
                 \ar[u]|{id_{\underline{3}}} &
 {\underline{2}} \ar[l]|{\nabla_{\underline{1}}\otimes id_{\underline{1}}}
                 \ar@{}[rd]|{A_6} &
 {\underline{2}} \ar[l]|{\gamma_{\underline{1},\underline{1}}} \ar[u]_{id_{\underline{2}}} \\
 {\underline{3}} \ar[u]^{id_{\underline{1}}\otimes \gamma_{\underline{1},\underline{1}}}
                 \ar@{}[rdd]|{A_7} &
 {\underline{3}} \ar[u]|{id_{\underline{1}}\otimes \gamma_{\underline{1},\underline{1}}}
                 \ar[l]|{id_{\underline{3}}} & &
 {\underline{2}} \ar[u]|{\gamma_{\underline{1},\underline{1}}}
                 \ar@{}[rd]|{A_8} &
 {\underline{2}} \ar[u]_{id_{\underline{2}}} \ar[l]|{id_{\underline{2}}} \\
 {\underline{3}} \ar[u]^{\gamma_{\underline{2},\underline{1}}} &
 {\underline{2}} \ar[u]|{id_{\underline{1}}\otimes \nabla_{\underline{1}}}
                 \ar@{}[rd]|{A_9} &
 {\underline{2}} \ar[l]|{\gamma_{\underline{1},\underline{1}}}
                 \ar@{}[rd]|{A_{10}} &
 {\underline{1}} \ar[l]|{\nabla_{\underline{1}}} \ar[u]|{\nabla_{\underline{1}}}
                 \ar@{}[rd]|{A_{11}} &
 {\underline{1}} \ar[l]|{id_{\underline{1}}} \ar[u]_{\nabla_{\underline{1}}} \\
 {\underline{2}} \ar[u]^{\nabla_{\underline{1}} \otimes id_{\underline{1}}} &
 {\underline{2}} \ar[u]|{\gamma_{\underline{1},\underline{1}}} \ar[l]^{id_{\underline{2}}} &
 {\underline{2}} \ar[u]|{id_{\underline{2}}} \ar[l]^{id_{\underline{2}}} &
 {\underline{1}} \ar[u]|{id_{\underline{1}}} \ar[l]^{\nabla_{\underline{1}}} &
 {\underline{1}} \ar[u]_{id_{\underline{1}}} \ar[l]^{id_{\underline{1}}}
}$
\end{center}
\caption{How to compose the cell $\hat{D}_\nabla$.}
\protect\label{excompfig}
\end{figure}

 The second cell $\hat{D}_\nabla$ defines a pullback, but it can be
 obtained by composition of other basic cells and identities, as
 illustrated in Figure~\ref{excompfig}. Let us comment on the
 composition. At the centre of the figure we find the cell $A_5 =
 D_{\nabla}$, in fact we recall that by the coherence axioms for
 duplicators (cf. Table~\ref{ThSigmatab}) we have
 $\nabla_{\underline{1}};\gamma_{\underline{1},\underline{1}} =
 \nabla_{\underline{1}}$, and by functoriality of tensor product we
 have \eg,
\[
 (id_{\underline{1}} \otimes \nabla_{\underline{1}}) ;
 (id_{\underline{1}} \otimes \gamma_{\underline{1},\underline{1}}) =
 (id_{\underline{1}} ; id_{\underline{1}}) \otimes
 (\nabla_{\underline{1}};\gamma_{\underline{1},\underline{1}}) =
 id_{\underline{1}} \otimes \nabla_{\underline{1}}.
\]
\noindent
 On the bottom-right part of the figure, we find the cells $A_8$
 and $A_{10}$ that are the horizontal and vertical identities of
 $\nabla_{\underline{1}}$, while $A_{11}$ is the trivial identity
 for the object $\underline{1}$. Then, note that $A_6 = A_9 =
 R_{\gamma}$. The cell $A_7$ is a horizontal identity, in fact by
 naturality of the symmetries, we have
\[
 \gamma_{\underline{1},\underline{1}} ;
 (id_{\underline{1}} \otimes \nabla_{\underline{1}}) =
 (\nabla_{\underline{1}} \otimes id_{\underline{1}}) ;
 \gamma_{\underline{2},\underline{1}}.
\]
\noindent
 Likewise, the cell $A_3$ is a vertical identity. Also $A_2$ and
 $A_4$ are obvious identities. The tile $A_1$ deserves more
 attention. The first thing to note is that by naturality of
 symmetries we have that
\[
 (\gamma_{\underline{1},\underline{1}}\otimes id_{\underline{1}});
 \gamma_{\underline{2},\underline{1}} =
 \gamma_{\underline{2},\underline{1}};
 (id_{\underline{1}}\otimes\gamma_{\underline{1},\underline{1}})
\]
\noindent
 and then, by coherence of symmetries, we have
\begin{eqnarray*}
 \gamma_{\underline{2},\underline{1}} & = &
 (id_{\underline{1}}\otimes\gamma_{\underline{1},\underline{1}});
 (\gamma_{\underline{1},\underline{1}}\otimes id_{\underline{1}})
 \\
 \gamma_{\underline{1},\underline{2}} & = &
 (\gamma_{\underline{1},\underline{1}}\otimes id_{\underline{1}});
 (id_{\underline{1}}\otimes\gamma_{\underline{1},\underline{1}})
\end{eqnarray*}
\noindent
 and therefore it follows that
\[
 \gamma_{\underline{2},\underline{1}};
 (id_{\underline{1}}\otimes\gamma_{\underline{1},\underline{1}}) =
 (id_{\underline{1}}\otimes\gamma_{\underline{1},\underline{1}});
 (\gamma_{\underline{1},\underline{1}}\otimes id_{\underline{1}});
 (id_{\underline{1}}\otimes\gamma_{\underline{1},\underline{1}}) =
 (id_{\underline{1}}\otimes\gamma_{\underline{1},\underline{1}});
 \gamma_{\underline{1},\underline{2}}.
\]
\noindent
 We can thus construct $A_1$ as illustrated in
 Figure~\ref{exauxfig}, where $A'_2$ is the vertical identity of
 $id_{\underline{1}}\otimes\gamma_{\underline{1},\underline{1}}$
 and $A'_4$ is the horizontal identity of
 $\gamma_{\underline{1},\underline{1}}\otimes id_{\underline{1}}$
 (for simplicity we omit to specify the borders of the
 cells, as they should be evident from the discussion above).
 To conclude that the composition in Figure~\ref{excompfig} yields
 $\hat{D}_\nabla$ we have to check that their borders are equal, and
 in fact observe that
\begin{eqnarray*}
 \gamma_{\underline{1},\underline{2}};
 (\gamma_{\underline{1},\underline{1}} \otimes id_{\underline{1}});
 (\gamma_{\underline{1},\underline{1}} \otimes id_{\underline{1}});
 \gamma_{\underline{2},\underline{1}} & = &
 \gamma_{\underline{1},\underline{2}};
 \gamma_{\underline{2},\underline{1}}  =
 id_{\underline{3}}
 \\
 \gamma_{\underline{2},\underline{1}};
 (id_{\underline{1}} \otimes \gamma_{\underline{1},\underline{1}});
 (id_{\underline{1}} \otimes \gamma_{\underline{1},\underline{1}});
 \gamma_{\underline{1},\underline{2}} & = &
 \gamma_{\underline{2},\underline{1}};
 \gamma_{\underline{1},\underline{2}}  =
 id_{\underline{3}}.
\end{eqnarray*}

\begin{figure}[t]
\begin{center}
$\xymatrix@+1pc{
 {\ } \ar@{}[rd]|{A_{11}\otimes R_{\gamma}} &
 {\ } \ar[l] \ar@{}[rd]|{A_2} &
 {\ } \ar[l] \ar@{}[rd]|{A'_2} &
 {\ } \ar[l] \\
 {\ } \ar[u] \ar@{}[rd]|{A'_4} &
 {\ } \ar[u] \ar[l] \ar@{}[rd]|{R_{\gamma}\otimes A_{11}} &
 {\ } \ar[u] \ar[l] \ar@{}[rd]|{A'_2} &
 {\ } \ar[u] \ar[l] \\
 {\ } \ar[u] \ar@{}[rd]|{A_4} &
 {\ } \ar[u] \ar[l] \ar@{}[rd]|{A_4} &
 {\ } \ar[u] \ar[l] \ar@{}[rd]|{A_{11}\otimes R_{\gamma}} &
 {\ } \ar[u] \ar[l] \\
 {\ } \ar[u] &
 {\ } \ar[u] \ar[l] &
 {\ } \ar[u] \ar[l] &
 {\ } \ar[u] \ar[l]
}$
\end{center}
\caption{How to obtain the cell $A_1$ in Figure~\ref{excompfig}.}
\protect\label{exauxfig}
\end{figure}

 The third cell $\hat{D}'_f$ illustrated in
 Figure~\ref{misstilesfig} is a pullback, but it can be composed
 starting from $\hat{D}_f$ as shown in Figure~\ref{exffig}, where
 unnamed cells are obvious (horizontal or vertical) identities. In
 writing the border of $\hat{D}_f$ we have exploited the coherence
 axiom
\[
 \nabla_{\underline{n}};\gamma_{\underline{n},\underline{n}} =
 \nabla_{\underline{n}}.
\]
\noindent
 The cells $B_3$ and $B_2$ are identities that exploit the
 naturality of symmetries. Finally, the cell $B_1$ is obtained by
 a construction analogous to that of $A_1$, employing $R_\gamma$
 as a building block.

\begin{figure}[t]
\begin{center}
$\xymatrix@C=+2cm{
 {\underline{2}} \ar@{}[rd]|{R_\gamma} &
 {\underline{2}} \ar[l]_{\gamma_{\underline{1},\underline{1}}} &
 {\underline{2}} \ar[l]_{\gamma_{\underline{1},\underline{1}}} & &
 {\underline{1}} \ar[ll]_{\nabla_{\underline{1}}} \\
 {\underline{2}} \ar[u]^{\gamma_{\underline{1},\underline{1}}}
                 \ar@{}[rddd]|{B_3} &
 {\underline{2}} \ar[u]|{id_{\underline{2}}} \ar[l]|{id_{\underline{2}}}
                 \ar@{}[rrrd]|{\hat{D}_f} &
 {\underline{2}} \ar[u]|{id_{\underline{2}}} \ar[l]|{\gamma_{\underline{1},\underline{1}}} & &
 {\underline{1}} \ar[u]_{id_{\underline{1}}} \ar[ll]|{\nabla_{\underline{1}}} \\
 {\underline{2}} \ar[u]^{\gamma_{\underline{1},\underline{1}}} &
 {\underline{n+1}} \ar[u]|{f\otimes id_{\underline{1}}}
                   \ar@{}[rrd]|{B_2} &
 {\underline{2n}} \ar[l]|{id_{\underline{n}}\otimes f} &
 {\underline{2n}} \ar[l]|{\gamma_{\underline{n},\underline{n}}} &
 {\underline{n}} \ar[u]_{f} \ar[l]|{\nabla_{\underline{n}}} \\
 & {\underline{n+1}} \ar[u]|{id_{\underline{n+1}}}
                     \ar@{}[rd]|{B_1} &
 {\underline{1+n}} \ar[l]|{\gamma_{\underline{1},\underline{n}}} &
 {\underline{2n}} \ar[l]|{f\otimes id_{\underline{n}}} \ar[u]|{id_{\underline{2n}}} &
 {\underline{n}} \ar[l]|{\nabla_{\underline{n}}} \ar[u]|{id_{\underline{n}}} \\
 {\underline{1+n}} \ar[uu]^{id_{\underline{1}}\otimes f} &
 {\underline{1+n}} \ar[u]|{\gamma_{\underline{1},\underline{n}}} \ar[l]^{id_{\underline{1+n}}} &
 {\underline{1+n}} \ar[u]|{id_{\underline{1+n}}} \ar[l]^{id_{\underline{1+n}}}&
 {\underline{2n}} \ar[u]|{id_{\underline{2n}}} \ar[l]^{f\otimes id_{\underline{n}}} &
 {\underline{n}} \ar[u]|{id_{\underline{n}}}\ar[l]|{\nabla_{\underline{n}}}
}$
\end{center}
\caption{How to compose the cell $\hat{D}'_f$.}
\protect\label{exffig}
\end{figure}

 We hope that the few examples above can help the reader in
 understanding the compositional mechanism of basic cells, as it will
 be especially useful in Section~\ref{TSLPsec}.

 For instance, we can state a few technical lemmata that can be proved
 by tile pastings similar to the cell compositions discussed above. As
 a shorthand, for any two cells
 $A\from\cell{t}{u}{id_{\underline{n}}}{id_{\underline{n}}}$ and
 $B\from\cell{s}{v}{id_{\underline{m}}}{id_{\underline{m}}}$ with $s,v\from
 \underline{n} \to \underline{m}$, we denote by $A\lhd B$ the
 composition $(A*1^s)\cdot B = (A\cdot 1_v)*B$.


\begin{lemma}\label{lemma1}
 Given any arrow $t\from\underline{n}\to\underline{m}\in
 \mathbf{Th}[\Sigma]$ that can be obtained without using dischargers,
 the cell $\cell{t}{t}{id_{\underline{n}}}{id_{\underline{n}}}$ can be
 generated by $\mathcal{B}(\Sigma)$.
\end{lemma}

\begin{proof}
 By hypothesis, the arrow $t$ can be expressed as the parallel and
 sequential composition of arrows in $\Sigma \cup
 \{\gamma_{\underline{1},\underline{1}}, \nabla_{\underline{1}},
 id_{\underline{1}}\}$; therefore, by functoriality of tensor product,
 $t$ can be finitely decomposed as
 $\sigma_1;\sigma_2;\cdots;\sigma_l$ where $\sigma_i =
 id_{\underline{k_i}} \otimes t_i \otimes id_{\underline{m_i}}$, with
 $t_i\in \Sigma \cup \{\gamma_{\underline{1},\underline{1}},
 \nabla_{\underline{1}}, id_{\underline{1}}\}$. Then, the cell
 $\cell{t}{t}{id_{\underline{n}}}{id_{\underline{n}}}$ is just the
 (diagonal) composition $A_1\lhd A_2 \lhd \ldots \lhd A_l$, with $A_i
 = 1_{\underline{k_i}} \otimes R_{t_i} \otimes 1_{\underline{m_i}}$.
\end{proof}

 Note that by adding the cells $R_f$ just for the operators of the
 signature, then we are able to construct the analogous cells for
 generic contexts $t$.

\begin{lemma}
 Given any arrows $t\from\underline{h}\to\underline{k}$ and
 $s\from\underline{m}\to\underline{n}$ in $\mathbf{Th}[\Sigma]$, the
 cells
 $\cell{t\otimes s}{\gamma_{\underline{n},\underline{k}}}
       {\gamma_{\underline{m},\underline{h}}}{s\otimes t}$
 and
 $\cell{\gamma_{\underline{n},\underline{k}}}{t\otimes
 s}{s\otimes t}{\gamma_{\underline{m},\underline{h}}}$
 can be generated by $\mathcal{B}(\Sigma)$.
\end{lemma}
\begin{proof}
 By Lemma \ref{lemma1}, we know that the cells
 $A=\cell{\gamma_{\underline{n},\underline{k}}}
 {\gamma_{\underline{n},\underline{k}}}
 {id_{\underline{n+k}}}
 {id_{\underline{n+k}}}$ and
 $B=\cell{\gamma_{\underline{h},\underline{m}}}
 {\gamma_{\underline{h},\underline{m}}}
 {id_{\underline{h+m}}}
 {id_{\underline{h+m}}}$
 are generated by the basis $\mathcal{B}$.
 By vertically composing $B$ with the horizontal identity
 of $\gamma_{\underline{m},\underline{h}}$, we get the cell
 $C = B\cdot 1_{\gamma_{\underline{m},\underline{h}}}
 \from \cell
 {\gamma_{\underline{h},\underline{m}}}
 {id_{\underline{m+h}}}
 {\gamma_{\underline{m},\underline{h}}}
 {id_{\underline{m+h}}}$. Then, the
 cell  $\cell{t\otimes s}{\gamma_{\underline{n},\underline{k}}}
       {\gamma_{\underline{m},\underline{h}}}{s\otimes t}$
 is obtained as the composition $A*1^{s\otimes t}*C$,
 because $\gamma_{\underline{h},\underline{m}};(s\otimes
 t);\gamma_{\underline{n},\underline{k}} = t\otimes s$.
 The cell $\cell{\gamma_{\underline{n},\underline{k}}}{t\otimes
 s}{s\otimes t}{\gamma_{\underline{m},\underline{h}}}$
 can be generated by a similar construction.
\end{proof}

 The second part of the previous lemma is an instance of a
 more general result.

\begin{lemma}\label{pbduallemma}
 If the cell $\cell{s}{u}{v}{t}$ is generated by the basis
 $\mathcal{B}(\Sigma)$, then also the cell $\cell{u}{s}{t}{v}$
 does.
\end{lemma}
\begin{proof}
 Obvious, by observing that the property holds for all cells in
 $\mathcal{B}(\Sigma)$ except $D_\nabla$, for which however
 we have shown how to generate its counterpart
 $\hat{D}_\nabla$.
\end{proof}

\begin{lemma}\label{lemmanabla}
 Given any arrow $t\from\underline{m}\to\underline{n}\in
 \mathbf{Th}[\Sigma]$ that can be obtained without using dischargers,
 the cells
 $\cell{\nabla_{\underline{n}}}{t\otimes
 t}{t}{\nabla_{\underline{m}}}$ and $\cell{t\otimes
 t}{\nabla_{\underline{n}}}{\nabla_{\underline{m}}}{t}$ can be
 obtained by composition of basic cells.
\end{lemma}


\begin{theorem}
 The basis $\mathcal{B}(\Sigma)$ generates all and only pullback squares
 of $\mathbf{Th}[\Sigma]$.
\end{theorem}

\begin{proof}
 The fact that all composed cells are pullbacks is
 straightforward, as all basic tiles are pullbacks and such a
 property is preserved by the three operations of the tile model
 (horizontal and vertical sequential compositions and parallel
 composition).

 The proof that all pullbacks can be obtained in this way is more
 subtle. We exploit the fact that, in the category
 $\mathbf{Th}[\Sigma]$, whenever the pullback of $\sigma$ and $\theta$
 exists and $\sigma$ can be decomposed as $\sigma_1;\sigma_2$, then
 also the pullback of $\sigma_2$ and $\theta$ exists (because
 $\sigma_2$ is less instantiated than $\sigma$). Since each arrow
 $\sigma$ in $\mathbf{Th}[\Sigma]$ can be finitely decomposed as
 $\sigma_1;\sigma_2;\cdots;\sigma_n$ where $\sigma_i =
 id_{\underline{k_i}} \otimes t_i \otimes id_{\underline{m_i}}$, with
 $t_i\in \Sigma \cup \{\gamma_{\underline{1},\underline{1}},
 \nabla_{\underline{1}},!_{\underline{1}}, id_{\underline{1}}\}$, then
 the pullback of $\theta$ and $\sigma$, if it exists, can be computed
 stepwise. In fact, the proof is by induction on the length $n$ of a
 fixed decomposition of $\sigma$. Thus, it reduces to prove that if
 the pullback of $\theta$ and $id_{\underline{k}} \otimes t \otimes
 id_{\underline{m}}$ (with $t\in \Sigma \cup
 \{\gamma_{\underline{1},\underline{1}},
 \nabla_{\underline{1}},!_{\underline{1}}, id_{\underline{1}}\}$)
 exists, then it is generated by $\mathcal{B}(\Sigma)$. We proceed by
 case analysis on $t$ and, for each case, by induction on the length
 of the decomposition of $\theta$, exploiting the besic cells in
 $\mathcal{B}(\Sigma)$ to cover all possible combinations.
\end{proof}


\subsection{Pullbacks as tiles}\label{PATsec}

 The finitary presentation of pullbacks can be straightforwardly used
 to build a tile system that generates the double category of pullbacks.

\begin{definition}[Tile system for pullbacks]
 Given a signature $\Sigma$, we define the tile system
 $\mathcal{R}_{\mathit{PB}(\Sigma)}$ such that its horizontal category is
 $\textbf{Th}[\Sigma]^{\mathrm{op}}$, its vertical category is
 $\textbf{Th}[\Sigma]^{\mathrm{op}}$ and the basic cells are those in
 $\mathcal{B}(\Sigma)$ (see Figure~\ref{basicpbkfig} and
 remember that horizontal and vertical
 identity tiles will be freely generated in the model).
\end{definition}

 The representation theorem can then be rephrased as below.

\begin{theorem}
 A cell $\cell{t}{u}{v}{s}$ is in $\mathscr{P}(\mathcal{C})$ if and
 only if $\mathcal{R}_{\mathit{PB}(\Sigma)} \vdash \cell{t}{u}{v}{s}$.
\end{theorem}

\section{Tile systems for logic programs}\label{TSLPsec}

 The idea is to transform a logic program into a tile system which is
 able to compute the same computed answer substitutions for each
 goal. To this aim, we will exploit the tiles presented for building
 pullbacks in the category of substitutions, which provide the
 unification mechanism for goal resolution.

\subsection{From logic programs to a logic of tiles}\label{FLPTLTsec}

 The tile system that we propose can be
 sketched as follows:

\begin{definition}[Tile system for logic programming]
 Given a pure logic program $\mathcal{P}$ on the alphabet $\Sigma$, we
 denote by $\mathcal{R}_{\mathcal{P}}$ the tile system specified by
 the following rules:
\begin{itemize}
\item
 There are two basic sorts $\mathsf{t}$ (for terms) and
 $\mathsf{p}$ (for predicates). Correspondingly, the interfaces
 are elements of $\{\mathsf{t},\mathsf{p}\}^*$ (as a matter of
 notation, we let $\epsilon$ denote the empty string of sorts,
 and denote by $\mathsf{t}^n$ the string composed by $n$
 occurrences of $\mathsf{t}$, and similarly for $\mathsf{p}$).

\item
 To each functional symbol $f$ with arity $n$ in the alphabet, we
 associate an operator $\dfun{f}{\mathsf{t}^n}{\mathsf{t}}$ in the
 signature of configurations, and to each predicate symbol $p$ (here
 $\Box$ can be viewed as a nullary predicate) with arity $k$ in the
 alphabet, we associate an operator
 $\dfun{p}{\mathsf{t}^k}{\mathsf{p}}$ in the signature of
 configurations. Then, we add the symbol $\_\wedge\_ \from
 \mathsf{p}^2 \to \mathsf{p}$ for modeling conjunction. (We will show
 that, without loss of generality, the conjunction operator can be
 more conveniently defined to be associative and with unit
 $\Box$.) The configurations are the arrows (of the op-category) of the
 free cartesian category generated by the signature of configurations.

\item
 To each functional symbol $f$ with arity $n$ in the alphabet, we
 associate an operator $\dfun{f}{\mathsf{t}^n}{\mathsf{t}}$ in the
 signature of observations (note that the symbol $f$ is thus
 overloaded, since it also appears in the horizontal
 dimension;
 however, this will not create any confusion).  Then, the
 observations are the arrows (of the op-category) of the free
 cartesian category generated by the signature of observations.

\item
 To each clause
\[
 c \mathrel{\equiv} p(t_1,\ldots,t_k)\ \mathrel{:-}\
                    q_1(\vec{s}_1),\ldots,q_m(\vec{s}_m)
\]
\noindent
 (over $n$ variables $\{x_1,\ldots,x_n\}$) in the logic program we
 associate a basic tile $T_c$ in our system whose initial
 configuration is $\dfun{p}{\mathsf{t}^k}{\mathsf{p}}$ (representing
 the predicate symbol in the head of $c$), whose final
 configuration is $\dfun{ q_1(\vec{s}_1)\wedge\ldots\wedge
 q_m(\vec{s}_m)}{\mathsf{t}^n}{\mathsf{p}}$ (representing the body of
 the clause), whose trigger is the identity
 $\dfun{id_{\mathsf{p}}}{\mathsf{p}}{\mathsf{p}}$ and whose effect is
 the tuple $\dfun{\langle
 t_1,\ldots,t_k\rangle}{\mathsf{t}^n}{\mathsf{t}^k}$ (representing the
 pattern to be matched by the arguments of predicate $p$). Note that
 the body of the clause may contain variables not appearing in the
 head (\ie, some of the $x_i$'s might not appear in the $t_i$'s) and
 consequently some discharger will be used in the effect of the
 tile. Moreover, since the same variable can be used more than once,
 duplicators can also be necessary (this is to remark the difference
 between the tupling
 $\langle t_1,\ldots,t_k\rangle$ and the tensorial product $t_1\otimes
 \cdots\otimes t_k$, as the former involves duplicators for
 expressing variable sharing).
 Since we take the op-categories the direction of all arrows is
 reversed \wrt\ the standard representation (see the tile $T_c$ in
 Figure~\ref{genclausetile}).

\item
 Finally, we add the basic tiles contained in
 $\mathcal{R}_{\mathit{PB}(\Sigma)}$ (see Figure~\ref{basicpbkfig}) for
 building pullbacks. We recall that just three of them depend on the alphabet
 under consideration, while the other three are common to all
 programs, \ie, they can be considered auxiliary to the framework.
\end{itemize}
\end{definition}

\begin{remark}
 When it is obvious from the context, we shall abuse the notation by
 avoiding to specify the involved sorts in the subscripts of $id$,
 $\nabla$, $\gamma$ and $!$, writing just the numbers of involved
 arguments (\eg, instead of $\gamma_{\mathsf{tp},\mathsf{p}}$ we shall
 write $\gamma_{\underline{2},\underline{1}}\from \mathsf{tpp} \to
 \mathsf{ptp}$).
\end{remark}

\begin{figure}[t]
\begin{center}
$\xymatrix@C=2cm{
 {\mathsf{p}} \ar@{}[rd]|{T_c} &
 {\mathsf{t}^k} \ar[l]_{p} \\
 {\mathsf{p}} \ar[u]^{id} &
 {\mathsf{t}^n} \ar[l]^{q_1(\vec{s}_1)\wedge\ldots\wedge q_m(\vec{s}_m)}
                \ar[u]_{\langle t_1,\ldots,t_k\rangle}
}$
\end{center}
\caption{}
\protect\label{genclausetile}
\end{figure}

 We can assume the operator $\wedge$ to be associative and with unit
 $\Box$ because all the basic tiles associated to the clauses have an
 identity as trigger. This, together with the fact that they are the
 only rewrite rules involving predicate symbols, means that rewrites
 are always enabled for predicates nested in conjunctions. For example
 in the expression $q_1(\vec{s}_1)\wedge\ldots\wedge q_m(\vec{s}_m)$
 it is not important the way in which the $q_i$'s are conjoined, as
 their evolutions do not interact with the `tree' of
 conjunctions. Thus, $q_0 \wedge (q_1 \wedge q_2)$ is equivalent to
 $(q_0 \wedge q_1) \wedge q_2$. Moreover,  we make the special symbol $\Box$
 be the unit for $\wedge$. These assumptions do not
 alter the `behavior' of the system, but allow us to simplify the
 notation and the presentation of main results.

 The intuition is that for each goal, we can compute a refutation in the
 tile system by starting from the associated configuration and
 constructing a tile whose final configuration is the empty
 goal (possibly in parallel with some dischargers that act
 as placeholders for the free variables in the computed answer
 substitution), \ie, the final configurations must have the
 form $\Box\otimes !_{\underline{n}}$ (without monoidality of
 $\wedge$ we should have considered as final configurations
 for termination any possible finite conjunction of empty
 goals). The effect of such a tile corresponds to the computed answer
 substitution.  The tiles with initial input interface $\mathsf{p}$
 and final configuration $\Box\otimes !_{\underline{n}}$ for $n\in
 \nat$ are called \emph{refutation tiles}.

 The following example should illustrate how the tile system can
 simulate logic programming computations.

\begin{figure}[t]
\hrule \ \\
 \centerline{Program clauses translation.}
\begin{center}
$\vcenter{\xymatrix@C=2cm{
 {\mathsf{p}} \ar@{}[rd]|{T_{c_1}} &
 {\mathsf{t}^2} \ar[l]_{p} \\
 {\mathsf{p}} \ar[u]^{id} &
 {\mathsf{t}^2} \ar[l]^{(\nabla_{\underline{1}}\otimes
                         id_{\underline{1}});
                        (q \otimes r);\wedge}
                \ar[u]_{f\otimes id_{\underline{1}}}
}}$
\hfill
$\vcenter{\xymatrix@C=2cm{
 {\mathsf{p}} \ar@{}[rd]|{T_{c_2}} &
 {\mathsf{t}^2} \ar[l]_{r} \\
 {\mathsf{p}} \ar[u]^{id} &
 {\epsilon} \ar[l]^{\Box} \ar[u]_{a\otimes a}
}}$
\hfill
$\vcenter{\xymatrix@C=2cm{
 {\mathsf{p}} \ar@{}[rd]|{T_{c_3}} &
 {\mathsf{t}^1} \ar[l]_{q} \\
 {\mathsf{p}} \ar[u]^{id} &
 {\epsilon} \ar[l]^{\Box} \ar[u]_{b}
}}$
\end{center}
\hrule \ \\ \ \\
\centerline{Auxiliary pullback tiles associated to the signature.}
\begin{center}
$\vcenter{\xymatrix@C-1pc{
 {\mathsf{t}} \ar@{}[rd]|{R_a} &
 {\epsilon} \ar[l]_{a} \\
 {\epsilon} \ar[u]^{a} &
 {\epsilon} \ar[l]^{id_{\underline{0}}} \ar[u]_{id_{\underline{0}}} }}$
\hfill
 $\vcenter{\xymatrix@C-1pc{
 {\mathsf{t}^2} \ar@{}[rd]|{D_a} &
 {\mathsf{t}} \ar[l]_{a\otimes id_{\underline{1}}} \\
 {\mathsf{t}} \ar[u]^{\nabla_{\underline{1}}} &
 {\epsilon} \ar[l]^{a} \ar[u]_{a} }}$
\hfill $\vcenter{\xymatrix@C-1pc{
 {\mathsf{t}^2} \ar@{}[rd]|{\hat{D}_a} &
 {\mathsf{t}} \ar[l]_{\nabla_{\underline{1}}} \\
 {\mathsf{t}} \ar[u]^{a\otimes id_{\underline{1}}} &
 {\epsilon} \ar[l]^{a} \ar[u]_{a} }}$
\hfill
$\vcenter{\xymatrix@C-1pc{
 {\mathsf{t}} \ar@{}[rd]|{R_b} &
 {\mathsf{t}} \ar[l]_{b} \\
 {\mathsf{t}} \ar[u]^{b} &
 {\epsilon} \ar[l]^{id_{\underline{0}}} \ar[u]_{id_{\underline{0}}} }}$
\hfill
 $\vcenter{\xymatrix@C-1pc{
 {\mathsf{t}^2} \ar@{}[rd]|{D_b} &
 {\mathsf{t}} \ar[l]_{b\otimes id_{\underline{1}}} \\
 {\mathsf{t}} \ar[u]^{\nabla_{\underline{1}}} &
 {\epsilon} \ar[l]^{b} \ar[u]_{b} }}$
\hfill
$\vcenter{\xymatrix@C-1pc{
 {\mathsf{t}^2} \ar@{}[rd]|{\hat{D}_b} &
 {\mathsf{t}} \ar[l]_{\nabla_{\underline{1}}} \\
 {\mathsf{t}} \ar[u]^{b\otimes id_{\underline{1}}} &
 {\epsilon} \ar[l]^{b} \ar[u]_{b} }}$
\end{center}
\begin{center}
$\vcenter{\xymatrix{
 {\mathsf{t}} \ar@{}[rd]|{R_f} &
 {\mathsf{t}} \ar[l]_{f} \\
 {\mathsf{t}} \ar[u]^{f} &
 {\mathsf{t}} \ar[l]^{id_{\underline{1}}} \ar[u]_{id_{\underline{1}}} }}$
\hfill
 $\vcenter{\xymatrix{
 {\mathsf{t}^2} \ar@{}[rd]|{D_f} &
 {\mathsf{t}^2} \ar[l]_{f\otimes id_{\underline{1}}} \\
 {\mathsf{t}} \ar[u]^{\nabla_{\underline{1}}} &
 {\mathsf{t}} \ar[l]^{f}
                 \ar[u]_{\nabla_{\underline{1}};
                         (id_{\underline{1}}\otimes f)} }}$
\hfill $\vcenter{\xymatrix@C+1pc{
 {\mathsf{t}^2} \ar@{}[rd]|{\hat{D}_f} &
 {\mathsf{t}} \ar[l]_{\nabla_{\underline{1}}} \\
 {\mathsf{t}^2} \ar[u]^{f\otimes id_{\underline{1}}} &
 {\mathsf{t}} \ar[l]^{\nabla_{\underline{1}};
                         (id_{\underline{1}} \otimes f)}
                 \ar[u]_{f} }}$
\end{center}
\hrule \ \\ \ \\
\centerline{Auxiliary pullback tiles independent of the
signature.}
\begin{center}
$\vcenter{\xymatrix{
 {\mathsf{t}^2} \ar@{}[rd]|{R_\nabla} &
 {\mathsf{t}} \ar[l]_{\nabla_{\underline{1}}} \\
 {\mathsf{t}} \ar[u]^{\nabla_{\underline{1}}} &
 {\mathsf{t}} \ar[l]^{id_{\underline{1}}} \ar[u]_{id_{\underline{1}}} }} $
\hfill $\vcenter{\xymatrix{
 {\mathsf{t}^2} \ar@{}[rd]|{R_\gamma} &
 {\mathsf{t}^2} \ar[l]_{\gamma_{\underline{1},\underline{1}}} \\
 {\mathsf{t}^2} \ar[u]^{\gamma_{\underline{1},\underline{1}}} &
 {\mathsf{t}^2} \ar[l]^{id_{\underline{2}}} \ar[u]_{id_{\underline{2}}} }}$
\hfill $\vcenter{\xymatrix{
 {\mathsf{t}^3} \ar@{}[rd]|{D_\nabla} &
 {\mathsf{t}^2} \ar[l]_{\nabla_{\underline{1}}\otimes id_{\underline{1}}} \\
 {\mathsf{t}^2} \ar[u]^{id_{\underline{1}}\otimes \nabla_{\underline{1}}} &
 {\mathsf{t}} \ar[l]^{\nabla_{\underline{1}}}
                 \ar[u]_{\nabla_{\underline{1}}} }}$
\end{center}
\hrule
\caption{The tile system associated to the logic program
$\mathcal{P}$.} \protect\label{protilefig}
\end{figure}

\begin{example}
 Let us consider the simple
 alphabet consisting of constants $a$ and $b$, unary function symbol
 $f$, unary predicate $q$ and binary predicates $p$ and $r$.

 Given the logic program $\mathcal{P}$ defined by the three clauses

\begin{alltt}
 \(c\sb{1} \equiv\) p(f(X1),X2) :-  q(X1), r(X1,X2).
 \(c\sb{2} \equiv\) r(a,a).
 \(c\sb{3} \equiv\) q(b).
\end{alltt}

\noindent
 the corresponding tile system is illustrated in
 Figure~\ref{protilefig}. The tiles in the first row are those
 associated to the three clauses of the program. The tiles in the
 second row are the basic pullbacks associated to the constants $a$, $b$
 of the alphabet, while the tiles in the third row are the basic
 pullbacks associated to the unary function symbol $f$ of the
 alphabet. The tiles in the fourth row are the auxiliary tiles common
 to all representations of logic programs. Note that, once the
 signature of terms is fixed, then all the auxiliary tiles
 are fixed, and the tiles for representing the logic
 program are in bijection with the clauses of the program.

 Now suppose one wants to compute the goal
 $\mathrel{?-}\ p(x_1,x_2)$. The idea is to compute all possible tiles
 that have $p\from \mathsf{t}^2 \to \mathsf{p}$ as initial
 configuration and the empty goal as conclusion. The effect
 of such tiles should in fact correspond to the computed answer
 substitutions of the program execution on the given goal. It is easy
 to argue that no such tile exists for the given goal. In fact, the
 only tile having $p$ as initial configuration is $T_{c_1}$ that leads
 to the configuration $(\nabla_{\underline{1}}\otimes
 id_{\underline{1}});(q\otimes r);\wedge$. Then $T_{c_3}$ and
 $T_{c_2}$ can be (concurrently) applied respectively to $q$ and to
 $r$, but the computation cannot be completed, as the coordination of
 the two resolutions is not possible. In fact the pullback of
 $b\otimes a$ and $\nabla_{\underline{1}}$ does not exist, and hence
 also the pullback of $b\otimes a\otimes a$ and
 $(\nabla_{\underline{1}}\otimes id_{\underline{1}})$ does not exist
 as well. The partial computation is illustrated in
 Figure~\ref{partcompfig}.

 If the third clause $c_3$ is replaced by $c'_3 \equiv \mathtt{q(a)}$,
 then we can compute the tile refutation illustrated in
 Figure~\ref{compcompfig}, where the tile $\alpha\from
 \cell{\nabla_{\underline{1}}}{a\otimes a}{a}{id_{\underline{0}}}$ can
 be obtained in any of the two ways illustrated in
 Figure~\ref{twowayfig}. The computed
 answer substitution $f(a)\otimes a$ (representing
 $[\sbtn{f(a)}{x_1},\sbtn{a}{x_2}]$) is given by the effect of the
 composed tile. Note that $c'_3$ and $c_2$ can be applied concurrently, \ie,
 the order in which they are applied is not relevant and moreover,
 they can also be performed in parallel, their outputs being
 coordinated by means of the tile $\alpha$. The two ways of building
 $\alpha$ show that the coordination mechanism does not depend on the
 order of execution of $T_{c'_3}$ and $T_{c_2}$, which is in fact
 immaterial.
\end{example}

\begin{figure}[t]
\begin{center}
$\vcenter{\xymatrix@C+1pc{
 {\mathsf{p}} \ar@{}[rrrd]|{T_{c_1}} & & &
 {\mathsf{t}^2} \ar[lll]_{p} \\
 {\mathsf{p}} \ar[u]^{id} &
 {\mathsf{p}^2} \ar[l]^{\wedge} &
 {\mathsf{t}^3} \ar[l]^{q \otimes r} &
 {\mathsf{t}^2} \ar[l]^{\nabla_{\underline{1}}\otimes
                         id_{\underline{1}}}
                \ar[u]_{f\otimes id_{\underline{1}}} \\
 {\mathsf{p}} \ar[u]^{id} &
 {\mathsf{p}^2} \ar[l]^{\wedge} \ar[u]^{id}
                \ar@{}[ru]|{T_{c_3}\otimes T_{c_2}} &
 {\epsilon} \ar[l]^{\Box \otimes \Box} \ar[u]_{b\otimes a\otimes a}
}}$
\end{center}
\caption{The incomplete derivation for $p$.}
\protect\label{partcompfig}
\end{figure}

\begin{figure}[t]
\begin{center}
$\vcenter{\xymatrix@C+2pc{
 {\mathsf{p}} \ar@{}[rrrd]|{T_{c_1}} & & &
 {\mathsf{t}^2} \ar[lll]_{p} \\
 {\mathsf{p}} \ar[u]^{id} &
 {\mathsf{p}^2} \ar[l]^{\wedge} &
 {\mathsf{t}^3} \ar[l]^{q \otimes r} &
 {\mathsf{t}^2} \ar[l]^{(\nabla_{\underline{1}}\otimes
                         id_{\underline{1}})}
                \ar[u]_{f\otimes id_{\underline{1}}} \\
 {\mathsf{p}} \ar[u]^{id} &
 {\mathsf{p}^2} \ar[l]^{\wedge} \ar[u]^{id}
                \ar@{}[ru]|{T_{c'_3}\otimes T_{c_2}} &
 {\epsilon} \ar[l]^{\Box \otimes \Box} \ar[u]|{a\otimes a\otimes a}
                \ar@{}[ru]|{\alpha\otimes 1_a} &
 {\epsilon} \ar[l]^{id_{\underline{0}}} \ar[u]_{a\otimes a}
}}$
\end{center}
\caption{The refutation for $p$.}
\protect\label{compcompfig}
\end{figure}

\begin{figure}[t]
\begin{center}
$\vcenter{\xymatrix{
 {\mathsf{t}^2} \ar@{}[rd]|{\hat{D}_a} &
 {\mathsf{t}} \ar[l]_{\nabla_{\underline{1}}} \\
 {\mathsf{t}} \ar[u]^{a\otimes id_{\underline{1}}} &
 {\epsilon} \ar[l]^{a} \ar[u]_{a} \\
 {\epsilon} \ar[u]^{a}
                \ar@{}[ru]|{R_a} &
 {\epsilon} \ar[l]^{id_{\underline{0}}} \ar[u]_{id_{\underline{0}}}
}}$
\hspace{1cm}
$\vcenter{\xymatrix{
 {\mathsf{t}^2} \ar@{}[rd]|{\hat{D}'_a} &
 {\mathsf{t}} \ar[l]_{\nabla_{\underline{1}}} \\
 {\mathsf{t}} \ar[u]^{id_{\underline{1}}\otimes a} &
 {\epsilon} \ar[l]^{a} \ar[u]_{a} \\
 {\epsilon} \ar[u]^{a}
                \ar@{}[ru]|{R_a} &
 {\epsilon} \ar[l]^{id_{\underline{0}}} \ar[u]_{id_{\underline{0}}}
}}$
\end{center}
\caption{Two ways for composing the tile $\alpha$ of
 Figure~\protect\ref{compcompfig}.}
\protect\label{twowayfig}
\end{figure}

 Notice that the use of tiles, thanks to its abstract flavour,
 completely frees the user from managing fresh variables, taking
 care in an automatic way of all the problems connected to name
 handling via the use of local placeholders.

\subsection{From clauses to tiles}\label{FCTTsec}

 We try to explain here informally the intuition that lies behind the
 definition of $\mathcal{R}_{\mathcal{P}}$. Basically, it is strictly
 related to the idea of building an \textsc{lts} out of a reduction
 system to study the interactions between composed components. From
 one point of view, it is evident that the reduction system of goal
 resolution summarized in Section~\ref{OSsec} considers the whole goal
 as an atomic entity, whose parts must all be coordinated. From this
 point of view, the clauses define the basic reduction steps that can
 be conveniently instantiated and contextualized. Indeed, the
 reduction perspective of logic programs has been investigated in
 \cite{CM:ASSTS}. However, to accomplish this view, one usually
 assumes to start with a set of variables large enough to contain all
 names that will be needed by all clause instances used in the
 refutation, as their dynamic creation cannot be modeled. This is a
 very strong assumption that somehow clashes against the desirable
 constructive presentation of computation, where fresh
 variables can be introduced by need.

 In \cite{Sew:RRBC,LM:DBCRS} it is suggested that instead of studying
 the behavior of a process in all possible contexts, the basic
 reduction rules of the system can be used to catch the least set of
 contexts that should be considered. This is obtained by considering
 all subterms of the sources of reduction rules. For example, if a
 reduction rewrites $f(g(a))$ to $h(b)$, then the essential contexts
 are $f(\_)$ and $f(g(\_))$, but not $h(\_)$, because only by
 embedding a term within these contexts a reduction may happen (unless
 it is already enabled inside the term itself). Unfortunately, this
 task is hard to accomplish in general, as the reduction semantics for
 process calculi usually impose suitable structural axioms on the
 processes. Nevertheless, the presence of sufficiently many
 \emph{relative pushouts} in the category of states is enough for
 guaranteeing that the universal constructions exist \cite{LM:DBCRS}.

 For logic programming, the problem of contextualization is reversed
 to the problem of instantiation, and we know in advance what are the
 interesting `internal' contexts, namely the pullback
 projections. This allows us to transform all clauses (seen as
 reduction rules) by moving as much internal context as possible to
 the observational part: We separate the topmost operator of the head
 of the clause (\ie, the
 predicate symbol) from its arguments (that are moved to the observational
 part, \ie, the effect of the tile) and
 then the basic pullbacks allow us to build incrementally all the
 other decompositions (in particular, we are speaking about tiles
 $R_f$, $R_\nabla$ and $R_\gamma$).

\begin{proposition}\label{pt1t2prop}
 For each tile $T_c\from \cell{p}{id}{t}{G}$ and all arrows $t_1,t_2$
 such that $t = t_1;t_2$ (with $t_2$ not involving dischargers), then
 the tile $\cell{t_2;p}{id}{t_1}{G}$ is entailed by
 $\mathcal{R}_{\mathcal{P}}$.
\end{proposition}
\begin{proof}
 The proof follows from Lemma~\ref{lemma1}, \ie, from the existence of
 the tile $\cell{t_2}{t_2}{id}{id}$ that can be vertically composed
 with $\cell{id}{t_1}{t_1}{id}$ (the horizontal identity for $t_1$),
 and with $T_c$ being horizontally composed with the result (see
 Figure~\ref{pt1t2fig}).
\end{proof}


\begin{figure}[t]
\begin{center}
$\xymatrix{
 {\mathsf{p}} \ar@{}[rdd]|{T_c} &
 {\mathsf{t}^k} \ar[l]_{p} &
 {\mathsf{t}^m} \ar[l]_{t_2} \\
 & {\mathsf{t}^m} \ar[u]_{t_2} &
 {\mathsf{t}^m} \ar[l]|{id_{\underline{m}}} \ar[u]_{id_{\underline{m}}} \\
 {\mathsf{p}} \ar[uu]^{id_{\underline{1}}} &
 {\mathsf{t}^n} \ar[l]^{G} \ar[u]_{t_1} &
 {\mathsf{t}^n} \ar[l]^{id_{\underline{n}}} \ar[u]_{t_1} }$
\end{center}
\caption{Graphical proof of Proposition~\protect\ref{pt1t2prop}.}
\protect\label{pt1t2fig}
\end{figure}

\begin{example}
 Let us consider the simple program

\begin{alltt}
 \(c\sb{1} \equiv\) sum(0,X1,X1).
 \(c\sb{2} \equiv\) sum(s(X1),X2,s(X3)) :- sum(X1,X2,X3).
\end{alltt}

\noindent
 over the signature consiting of constant $0$, unary symbol $s$ and
 ternary predicate symbol $\mathit{sum}$. The possible interactive
 decompositions of the heads of the two clauses are:
\begin{itemize}
\item
 for $c_1$: (1) $\mathit{sum}(0,x_1,x_2)$ with observation
 $\nabla_{\underline{1}}$, (2) $\mathit{sum}(x_1,x_2,x_2)$ with
 observation $0\otimes id_{\underline{1}}$, (3)
 $\mathit{sum}(x_1,x_2,x_3)$ with observation
 $0\otimes\nabla_{\underline{1}}$, and (4) $\mathit{sum}(0,x_1,x_1)$
 with observation $id_{\underline{1}}$;

\item
 for $c_2$: (1) $\mathit{sum}(s(x_1),x_2,x_3)$ with observation
 $id_{\underline{2}}\otimes s$, (2) $\mathit{sum}(x_1,x_2,s(x_3))$
 with observation $s\otimes id_{\underline{2}}$, (3)
 $\mathit{sum}(x_1,x_2,x_3)$ with observation $s\otimes
 id_{\underline{1}} \otimes s$, and finally (4)
 $\mathit{sum}(s(x_1),x_2,s(x_3))$ with observation
 $id_{\underline{3}}$.
\end{itemize}

\noindent
 Although the basic tiles of the tile system associated to the program
 just consider decompositions of kind (3), which are the most
 general, by parallel and sequential composition with (basic)
 pullback tiles, the tile logic associated to the tile system will
 entail all the other decompositions.
\end{example}

 Note that tiles allow one to move contexts along states and
 observations in a very natural and uniform way.
 The interactivity of the tile representation relies on the fact that
 the effects of basic tiles associated to the clauses must be accepted
 by the current instantiation of the matched predicate in the goal,
 otherwise the step cannot take place.

\begin{theorem}[Correspondence between (SLD-)derivations and tiles]
\label{reptheo}
 Let $\mathcal{P}$ be a logic program and $G$ a goal. Then,
\begin{enumerate}
\item
 if $\mathcal{P}\vvdash G \Rightarrow_{\sigma} G'$, then
 $\mathcal{R}_{\mathcal{P}}\vdash \cell{G}{id}{\theta}{G'}$ with
 $\theta=\sigma_{|\mathit{Var}(G)}$;

\item
 if $\mathcal{R}_{\mathcal{P}}\vdash \cell{G}{id}{\theta}{G'}$, then
 there exists $\sigma$ with $\theta=\sigma_{|\mathit{Var}(G)}$ such
 that $\mathcal{P}\vvdash G \Rightarrow^*_{\sigma} G'$.
\end{enumerate}
\end{theorem}

\begin{proof}
 The proof of point 1 proceeds by rule induction. For the `empty goal'
 rules we rely on the fact that $\Box$ is the unit for $\wedge$
 and that the vertical identities always exist. For the `atomic goal'
 we rely on the results of Section~\ref{RVPsec} on the correspondence
 between mgu's and pullbacks while applying the tile $T_{H
 \mathrel{:-} F}$ to the goal $A$. For the `conjunctive goal' rules,
 the difficulty is that $G$ and $G'$ might share some variables. In
 fact, by inductive hypothesis we can assume that
 $\mathcal{R}_{\mathcal{P}}\vdash \cell{G}{id}{\sigma}{F}$ and
 therefore we must employ the pullback tiles for propagating $\sigma$
 to $G'$. This can be done by exploiting the tiles $\hat{D}_f$ and
 $D_{\nabla}$.

 For proving the point 2, we fix a decomposition of
 $\cell{G}{id}{\theta}{G'}$ in terms of basic tiles of
 $\mathcal{R}_{\mathcal{P}}$ and then we proceed by induction on the
 number of tiles $T_c$ used for building $\cell{G}{id}{\theta}{G'}$.
\end{proof}

 Note that a tile can represent in general a whole sequence of derivation
 steps.

\begin{corollary}
  Let $\mathcal{P}$ be a logic program and $G$ a goal. Then,
\begin{enumerate}
\item
 if $\mathcal{P}\vdash_\sigma G$, then
 $\mathcal{R}_{\mathcal{P}}\vdash \cell{G}{id}{\theta}{\Box \otimes
 !_{\underline{n}}}$ with $\theta=\sigma_{|\mathit{Var}(G)}$ and $n$
 the number of free variables in $\theta$;

\item
 if $\mathcal{R}_{\mathcal{P}}\vdash \cell{G}{id}{\theta}{\Box \otimes
 !_{\underline{n}}}$, then
 there exists $\sigma$ with
 $\theta=\sigma_{|\mathit{Var}(G)}$ such
 that $\mathcal{P}\vdash_\sigma G$.
\end{enumerate}
\end{corollary}

\subsection{Recovering ordinary semantics}\label{ROSsec}

 From the tile system $\mathcal{R}_{\mathcal{P}}$ we are able to recover
 several well-known semantics for logic programs.

\begin{itemize}
\item
 The \emph{least Herbrand model}, which gives the ordinary
 model-theoretic semantics for logic programs \cite{EK:SPLPL}, is
 given by refutation tiles whose initial configuration is a ground
 atomic goal:

\[
 \mathrm{Op}_1(\mathcal{P}) =
 \{ A\from \epsilon \to \mathsf{p} \mid
 \mathcal{R}_{\mathcal{P}}\vdash
 \cell{A}
      {id_{\underline{1}}}
      {!_{\underline{n}}}
      {\Box\otimes !_{\underline{n}}} \}.
\]

\item
 The \emph{correct answer substitutions} are given by the instances of
 initial configurations of refutation tiles that are (possibly
 non-ground) atomic goals:

\[
 \mathrm{Op}_2(\mathcal{P}) =
 \{ A\from \mathsf{t}^k \to \mathsf{p} \mid
 \mathcal{R}_{\mathcal{P}}\vdash
 \cell{A}
      {id_{\underline{1}}}
      {id_{\underline{k}} \otimes !_{\underline{k+n}}}
      {\Box\otimes !_{\underline{n}}} \}.
\]

\item
 The \emph{computed answer substitutions}, which define a useful
 semantic framework for addressing compositionality, concrete
 observables and program analysis \cite{FLMP:DMOBLL,BGLM:SSA}, can be
 immediately obtained by considering the refutation tiles with a
 single predicate as initial configuration:

\[
 \mathrm{Op}_3(\mathcal{P}) =
 \{ \theta;p\from \mathsf{t}^k \to \mathsf{p} \mid
 p\in\Sigma_{\Pi},\
 \mathcal{R}_{\mathcal{P}}\vdash
 \cell{p}
      {id_{\underline{1}}}
      {\theta\otimes !_{\underline{n}}}
      {\Box\otimes !_{\underline{k+n}}} \}.
\]

\item
 The \emph{resolvents} can be obtained by considering also non
 refutation tiles:

\[
 \mathrm{Op}_4(\mathcal{P}) =
 \{ (\theta;p,G) \mid
 p\in\Sigma_{\Pi},\
 \mathcal{R}_{\mathcal{P}}\vdash
 \cell{p}
      {id_{\underline{1}}}
      {\theta}
      {G} \}.
\]
\end{itemize}

 All the correspondences above follow as easy corollaries to the
 representation Theorem~\ref{reptheo}.

\subsection{Goal compositionality}\label{GCsec}

 Though compositionality issues for the classical semantics have been
 extensively studied in the literature, we want to focus here on
 compositionality of goals \wrt\ the two main operations discussed in
 the Introduction, namely instantiation and conjunction
 (AND-compositionality). We focus on goal equivalence for a given
 program $\mathcal{P}$; thus,
 the main questions are: (1) When are two goals equivalent? (2) Is
 equivalence a congruence?

 Inspired by the connections with the area of process description
 calculi that motivated our approach, and having at hand an
 established theory developed for trace equivalence and bisimilarity
 in the tile setting, the natural step is to try to apply general
 existing techniques to our special case.  Therefore we can answer
 question (1) by defining the two equivalences:

\begin{enumerate}
\renewcommand{\theenumi}{\alph{enumi}}
\item
 $G \simeq_{\mathcal{P}} G'$ if $\mathcal{T}_{\mathcal{P}}(G) =
 \mathcal{T}_{\mathcal{P}}(G')$, where $\mathcal{T}_{\mathcal{P}}(G)
 \stackrel{\mathrm{def}}{=}\{\theta \mid
 \mathcal{R}_{\mathcal{P}}\vdash \cell{G}{id_{\underline{1}}}
 {\theta}{\Box\otimes id_{\underline{n}}} \}$.

\item
  $G \cong_{\mathcal{P}} G'$ if $G$ and $G'$ are tile bisimilar in
  $\mathcal{R}_{\mathcal{P}}$.
\end{enumerate}

 These equivalences are reminiscent of the analogous notions on the
 processes of a fixed process description calculus modeled with
 tiles. The interactive part of the underlying tile system tells what
 can be observed during the computation, and then the equivalences
 arise naturally as behavior-based concepts.

 Now, question (2) corresponds to ask whether $G \simeq G'$ implies
 that $G\wedge F \simeq G'\wedge F$ and $\sigma;G \simeq \sigma;G'$
 for all $F$ and $\sigma$ or not (the same for $\cong$).

 Though proving directly these properties is not too complicate, we can exploit
 Proposition~\ref{decascongprop} and just prove that the tile system
 $\mathcal{R}_{\mathcal{P}}$ enjoys the decomposition property for any
 logic program $\mathcal{P}$.

\begin{proposition}
 For any logic program $\mathcal{P}$, the corresponding tile system
 $\mathcal{R}_{\mathcal{P}}$ enjoys the sequential decomposition
 property.
\end{proposition}

\begin{proof}
 We want to prove that for any goal $\sigma;G$ and tile
 $\mathcal{R}_{\mathcal{P}} \vdash
 \cell{\sigma;G}{id_{\underline{1}}}{\theta}{F}$, there exist
 $\theta'$, $\sigma'$ and $F'$ such that $\mathcal{R}_{\mathcal{P}}
 \vdash \cell{G}{id_{\underline{1}}}{\theta'}{F'}$ and
 $\mathcal{R}_{\mathcal{P}} \vdash
 \cell{\sigma}{\theta'}{\theta}{\sigma'}$. Fixed a decomposition of
 $\cell{\sigma;G}{id_{\underline{1}}}{\theta}{F}$ in terms of basic
 tiles, the proof proceeds by induction on the number of tiles
 associated to the clauses that are considered in the decomposition.
\end{proof}

\begin{corollary}
 For any logic program $\mathcal{P}$, the equivalences
 $\simeq_{\mathcal{P}}$ and $\cong_{\mathcal{P}}$ are congruences with
 respect to conjunction of goals and instantiation of free variables.
\end{corollary}

\subsection{Three goal equivalences via instantiation closures}\label{THREEsec}

 One of the main motivations for the research presented in this paper
 concerns the application of logic programming as a convenient
 computational model for interactive systems. In particular, the
 unification mechanism typical of resolution steps is particularly
 interesting because it differs from the ordinary matching procedures
 of reduction semantics \cite{BB:CAM,Mil:CCS,Mes:CRL}. To some extent,
 mgu's characterizes the minimal amount of dynamic interaction
 with the rest of the system that is needed to evolve. In this section
 we compare other operational alternatives, which are commonly used in
 many concurrent systems and calculi, by means of the equivalences
 they induce on goals.  Each alternative is obtained by slightly
 modifying the operational rule for atomic goals.

 The first model allows for applying only ground instances of the
 clauses (to ground goals only):

\[
 (1) \irule{(H \mathrel{:-} F) \in \mathcal{P}\ \ \
        A = \sigma;H\ \mathrm{ground}\ \ \
        \sigma;F\ \mathrm{ground}} 
        {\mathcal{P}\vvdash A\Rightarrow_{\sigma}
                            \sigma;F}
\]
 
\noindent
 Then, two goals $G_1$ and $G_2$ (not necessarily ground) are
 equivalent, written $G_1 \mathrel{\sim_{(1)}} G_2$ if and only if for
 any ground substitution $\sigma$ on $\mathit{Var}(G_1,G_2)$, whenever
 $\sigma;G_1$ is refuted then also $\sigma;G_2$ is refuted, and vice
 versa. This equivalence is the most widely used for interactive
 systems (closing open systems in all possible ways), since it is the
 coarser ``correct'' equivalence that can be defined according to the
 operational rules. The disadvantage is that to check goal equivalence
 we must instantiate \wrt\ all ground substitutions, \ie, proving goal
 equivalence is in general very expensive.

 The second model allows for applying any instance of the
 clause to any matching instance of the goal:

\[
 (2) \irule{(H \mathrel{:-} F) \in \mathcal{P}\ \ \
        \sigma;A = \sigma;\rho;H} 
        {\mathcal{P}\vvdash A\Rightarrow_{\sigma}
                            \sigma;\rho;F}
\]
 
\noindent
 In this case, two goals $G_1$ and $G_2$ are equivalent, written $G_1
 \mathrel{\sim_{(2)}} G_2$ if and only if whenever $G_1$ can be
 refuted with $\sigma$, then also $G_2$ can be refuted with $\sigma$,
 and vice versa. This equivalence extends the previous one to a
 uniform treatment of open and ground goals, but of course equivalence
 proofs become even more complicated and inefficient.

 The third model is the ordinary one, where the substitution $\sigma$
 in (2) must be the mgu between $A$ and $\rho;H$. Hence, two goals
 $G_1$ and $G_2$ are equivalent, written $G_1 \mathrel{\sim_{(3)}}
 G_2$ if and only if they have the same set of computed answer
 substitutions (\ie, $\mathrel{\sim_{(3)}}$ is the equivalence
 $\mathrel{\simeq_{\mathcal{P}}}$ discussed in Section~\ref{GCsec}).
 This equivalence is very convenient, because it makes the transition
 system finitely branching (as opposed to (1) and (2)) and therefore
 facilitates equivalence proofs.

 If we work with an infinite set of function symbols, it can be easily
 verified that $\mathrel{\sim_{(1)}}$ and $\mathrel{\sim_{(2)}}$
 define exactly the same equivalence classes. The inclusion of
 $\mathrel{\sim_{(2)}}$ into $\mathrel{\sim_{(1)}}$ is obvious,
 because ground substitutions are just a particular case of generic
 substitutions. The converse holds because the existence of a
 refutation with ground substitution $\sigma;\psi$, where $\psi$
 contains function symbols not appearing in the program, implies the
 existence of another refutation with non-ground substitution
 $\sigma$. Therefore, the equivalence over ground substitutions
 ($\mathrel{\sim_{(1)}}$) together with the assumption of an infinite
 set of function symbols imply the equivalence over non-ground
 substitutions ($\mathrel{\sim_{(2)}}$).

 The equivalence $\mathrel{\sim_{(3)}}$ is instead stricter than the
 other two. Again, the inclusion of $\mathrel{\sim_{(3)}}$ in
 $\mathrel{\sim_{(1)}}$ is obvious, while it is easy to find an
 example of a logic program $\mathcal{P}$ where two goals have
 different sets of computed answer substitutions but have the same
 sets of ground refutations. Just consider a logic program with the
 following three facts:

\begin{alltt}
 p(X).
 p(a).
 q(X).
\end{alltt}

\noindent
 If we take the goals $p(X)$ and $q(X)$, it is immediate to see that $p(X)
 \mathrel{\sim_{(1)}} q(X)$. However, the set of computed answer
 substitutions of $p(X)$ is $\{\varepsilon, [\sbtn{a}{X}] \}$, while
 for $q(X)$ we just have $\{\varepsilon\}$ (with $\varepsilon$
 denoting the empty substitution).

\subsection{Concurrency and causality}\label{DTsec}

 If we look at the  system $\mathcal{R}_{\mathcal{P}}$ from a
 concurrent viewpoint then atomic goals can be regarded as distributed
 components that can evolve separately and where variable sharing
 provides the means to exchange information between
 components. According to this perspective,  \eg, for
 backtracking, it is essential to keep
 track of the causal dependencies among components.

 To accomplish this view we slightly modify the associated tile system
 for defining more concrete observations on the causal dependencies
 among replaced and inserted goals. To this aim, to each clause
\[
 c \mathrel{\equiv} p(t_1,\ldots,t_k)\ \mathrel{:-}\
                    q_1(\vec{s}_1),\ldots,q_m(\vec{s}_m)
\]
\noindent
 in the logic program, we associate an operator
 $\dfun{c}{\mathsf{p}^m}{\mathsf{p}}$ in the signature of
 observations. Then, since we want to be aware of the components
 distributed in the system, we do not consider the operator $\wedge$
 and associate to each clause $C$ the tile

\[
 C_c =
 \cell{p}
      {c}
      {\langle t_1,\ldots,t_k\rangle}
      {\langle q_1(\vec{s}_1),\ldots,q_m(\vec{s}_m)\rangle}.
\]

\noindent
 Note that by using the
 trigger $c$ we can now observe that the initial configuration $p$
 generates $m$ new components that causally depends on it.

 For the rest, we add as before the pullback tiles that provide the
 coordination mechanism about local instantiations.  In the new
 setting, equivalent computations from the point of view of
 concurrency and coordination are identified, whereas computations
 that return the same computed answer substitution but that employ
 different concurrent reduction strategies are distinguished. This
 also allows one to observe causal dependencies among resolution
 steps, since the triggers of refutation tiles describe the `concurrent
 strategy' employed for achieving the result.

 Of course, the notion of refutation tile slightly changes according
 to the above modification: A refutation tile is an entailed tile of
 the form $\cell{G}{s}{\theta}{\Box^m\otimes !_{\underline{n}}}$, \ie,
 empty goals become \emph{nil} processes distributed around system
 locations.

 The trigger of the refutation tile for a generic goal is a tuple of
 terms (without shared variables), \ie, it corresponds to an ordered
 forest of (ordered) trees, whose nodes are labeled with clause
 names. We denote by $\sqsubseteq$ the obvious partial order on nodes
 such that $x \sqsubseteq y$ iff $y$ descends from $x$.  Moreover,
 since the tree is ordered, we have an immediate correspondence
 between each clause instance and the subgoal it was applied to. Then,
 we can characterize the concurrency of the framework by means of the
 following theorem.

\begin{theorem}
 Let $\cell{G}{s}{\theta}{\Box^m\otimes !_{\underline{n}}}$ be a tile
 refutation for the goal $G$, and let $\sqsubseteq$ be the partial
 order (forest) associated to $s$. Moreover, let $\preceq$ be any
 total order that extends $\sqsubseteq$. Then by applying the clauses
 associated to the nodes of the tree in the order specified by
 $\preceq$ we obtain again the computed answer substitution $\theta$.
\end{theorem}

 The proof is based on the compositional properties of pullbacks and
 expresses the `complete concurrency' (from the trigger side, not from
 the effect side) of the framework.

 Since application of clauses that do not depend on each other
 (in $\sqsubseteq$) can be executed in any order by choosing suitable
 total orders $\preceq$, it follows that the order in which they are
 executed is not important. Note however that this depends on the
 fact that the coordination mechanism via pullbacks takes care of the
 side-effects of each clause application.

\section{Tiles and constraints}\label{CLPsec}

 In this section we informally discuss how the tile-based approach can
 be extended to deal with constraint logic programming (\textsc{clp})
 \cite{MS:PCI,JM:CLPS}.  Computational equivalences between the
 ordinary operational semantics of \textsc{clp} and the tile semantics
 we will briefly describe in this section can be established by
 results analogous to Theorem~\ref{reptheo}.  The interest in
 constraint satisfaction problems is centered around a powerful,
 declarative mechanism for knowledge representation, as many
 situations can be conveniently modeled by means of constraints on a
 set of objects or parameters. Therefore, constraint logic programming
 is not a language in itself, but can be more precisely seen as a
 scheme, parametric \wrt\ the kind of constraints that can be
 handled. For example, pure logic programming is to some extent a
 version of \textsc{clp} dealing with term equalities over a Herbrand
 universe. The way in which constraints are combined and simplified is
 delegated to a \emph{constraint solver} for efficiency reasons. Other
 formalisms, like \eg\ \emph{constraint handling rules}
 \cite{Fru:CHR}, allow for modeling solvers by means of suitable
 guarded clauses. Usually, constraint programming languages are
 monotonic (or \emph{non-consuming}), that is constraints are never
 deleted from the constraint store; however, in the literature there
 are some variants which allow for constraint consumption
 \cite{BdBP:POSOS}. Both the monotonic and the consuming behaviors
 can be represented in our framework.

 At the abstract level (see \cite{Sar:CC}), a \emph{constraint system}
 can be seen as a pair $\langle D,\vdash\rangle$, where $D$ is a set of
 \emph{primitive constraints} and $\vdash\subseteq \wp(D) \times D$ is
 the \emph{entailment relation}, relating (finite) sets of primitive
 constraints to entailed primitive constraints. Relation $\vdash$ must
 satisfy

\begin{itemize}
\item
 $\mathbf{C}\cup\{\mathbf{c}\} \vdash \mathbf{c}$ (reflexivity);
\item
 if $\mathbf{C} \vdash \mathbf{c}$ for all $\mathbf{c}\in
 \mathbf{C'}$, and $\mathbf{C'}\vdash \mathbf{c'}$, then
 $\mathbf{C}\vdash \mathbf{c'}$ (transitivity).
\end{itemize}

 The set of subsets of $D$ which are closed under entailment is
 denoted by $\abs{D}$, and a \emph{constraint} is just an element of
 $\abs{D}$. As usual, we assume that a set $\mathit{Con} \subseteq
 \abs{D}$ of \emph{consistent constraints} is given such that:

\begin{itemize}
\item
 if $\mathbf{C}\cup \mathbf{C'} \in \mathit{Con}$, then
 $\mathbf{C},\mathbf{C'}\in\mathit{Con}$;
\item
 if $\mathbf{c}\in D$ then $\{\mathbf{c}\}\in\mathit{Con}$;
\item
 if $\mathbf{C}\in\mathit{Con}$ and $\mathbf{C}\vdash \mathbf{c}$, then
 $\mathbf{C}\cup\{\mathbf{c}\}\in \mathit{Con}$.
\end{itemize}

 For our representation, a constraint system can be equivalently seen
 as a category $\mathcal{C}$ whose arrows are constraints and whose
 composition is the conjunction of constraints, in such a way that
 $\mathbf{C};\mathbf{c} = \mathbf{C}$ iff $\mathbf{C}\vdash
 \mathbf{c}$. We also assume a distinguished arrow $\mathbf{ff}$
 exists such that $\mathbf{C} = \mathbf{ff}$ iff $\mathbf{C}\not\in
 \mathit{Con}$.

 In the presence of constraints, goals become pairs $(G,\mathbf{C})$,
 where $G$ is an ordinary conjunctive formula and $\mathbf{C}$ is a
 constraint, while clauses can have the more general form

\[H \mathrel{:-} \mathbf{c_1} | B_1,\ldots,B_n,\mathbf{c_2}\]

\noindent
 where $\mathbf{c_1}$ is a \emph{guard} for the application of the
 clause (similar to the $\mathit{ask}$ operation of \emph{concurrent
 constraint programming} (\textsc{ccp}) \cite{Sar:CC}), and
 $\mathbf{c_2}$ is the constraint to be added to the store after the
 application of the clause (similar to the $\mathit{tell}$ operation
 of \textsc{ccp}). In the ordinary interpretation, the meaning is
 that the clause can be applied only if the constraint component of
 the current goal entails $\mathbf{c_1}$ and that, after the
 resolution step, the constraint $\mathbf{c_2}$ is added to the
 current state, provided that the resulting constraint is consistent,
 \ie, the resolution can be applied only if $\mathbf{C}\vdash
 \mathbf{c_1}$ and $\mathbf{C}\cup \{\mathbf{c_2}\} \in \mathit{Con}$.
 Although usually \textsc{clp} languages do not have guards in their
 syntax but just constraints in the bodies of the clauses (which
 correspond to the tell constraint $\mathbf{c_2}$ above), we decide to
 consider this more general kind of clauses in order to model also
 concurrent formalisms such as \textsc{ccp} and constraint rewriting
 formalisms such as \textsc{chr}.

 Now, we face several alternatives for describing the interaction
 between ask/tell and the current store, where each alternative
 corresponds to a different set of auxiliary tiles associated with the
 constraint system $\mathcal{C}$.

 For example, likewise pure logic programming, we can take the
 pullback squares in $\mathcal{C}$ (if any), or more generally, we can
 consider the \emph{relative pullbacks}, dualizing the approach of
 Leifer and Milner based on relative pushouts \cite{LM:DBCRS}. In this
 case, given a constraint $\mathbf{C}$ (the current constraint store)
 and another constraint $\mathbf{c_2}$ (the tell part of the clause),
 we have coordination tiles of the form
 $\cell{\mathbf{C}}{\mathbf{c_2}}{\mathbf{c}}{\mathbf{C'}}$ (with the
 condition that $\mathbf{c};\mathbf{C} \neq \mathbf{ff}$) expressing
 that $\mathbf{C'}$ is the minimal constraint to be added to
 $\mathbf{c_2}$ for entailing (all constraints in) $\mathbf{C}$, and
 that $\mathbf{c}$ is the minimal constraint to be added to
 $\mathbf{C}$ for entailing $\mathbf{c_2}$. Therefore, tiles of this
 kind check the consistency of $\mathbf{c_2}$ with $\mathbf{C}$ and
 return the additional amount of information gained by joining the two
 constraints, an operation which is suitable for interpreting tell
 constraints. The guard $\mathbf{c_1}$ should be considered as part of
 the initial configuration of the tile associated with the clause, so
 that the clause can be applied only if the current store $\mathbf{C}$
 can be decomposed as $\mathbf{C_1};\mathbf{c_1}$, while
 $\mathbf{c_2}$ is an effect of the tile (to be coordinated with the
 current state). Since the ask and tell operations are not consuming,
 the join of $\mathbf{c_1}$ and $\mathbf{c_2}$ must be inserted also
 in the final configuration. The resulting tile associated with the
 clause is thus
 $\cell{(P,\mathbf{c_1})}{id}{(t,\mathbf{c_2})}{(B_1,\ldots,B_n,\mathbf{c_2};\mathbf{c_1})}$,
 with $P$ the predicate symbol in $H$ and $t;P = H$.

 If the category describing the constraint system does not possess the
 pullbacks, we can consider all commuting squares, instead of just
 (relative) pullbacks. This encoding can be applied to a generic
 category $\mathcal{C}$, but usually involves an infinite number of
 possible closures.

 Notice that this way of modeling \textsc{clp} clauses via tiles
 synchronizes $P$ and $\mathbf{c_1}$ and therefore centralizes the
 control, unless $\mathbf{c_1}$ is the empty constraint.  An
 alternative, which solves this problem and gives more emphasis to the
 interaction between subgoals and constraints, is to leave the
 consistency check of the tell operation to the metainterpreter (\eg,
 by discarding all computations that reach an inconsistent store), and
 use the guard $\mathbf{c_1}$ as an effect, to abandon the centralized
 view. Now, the auxiliary tiles for constraints have just the task of
 checking the entailment of the guard in the current store, and
 therefore we can take all squares of the form
 $\cell{\mathbf{C}}{\mathbf{c_1}}{id}{\mathbf{C}}$ such that
 $\mathbf{C};\mathbf{c_1}=\mathbf{C}$ (there is exactly one cell for
 any $\mathbf{C},\mathbf{c_1}$ such that $\mathbf{C}\vdash
 \mathbf{c_1}$). Since $\mathbf{C}$ appears in the final
 configuration, there is no need for reasserting $\mathbf{c_1}$, and
 thus the tile associated with the generic clause is
 $\cell{P}{id}{(t,\mathbf{c_1})}{(B_1,\ldots,B_n,\mathbf{c_2})}$. Note
 that if tiles like $\cell{\mathbf{C}}{\mathbf{c_1}}{id}{\mathbf{C'}}$
 with $\mathbf{C'};\mathbf{c_1}=\mathbf{C}$ were considered instead,
 then the constraint $\mathbf{c_1}$ might also be consumed during the
 entailment check, unless it was reintroduced in the final
 configuration.

 It is worth to notice that in all these proposals to model
 \textsc{clp} via tiles, the tile approach allows us to clearly
 separate the rules of the program from the coordination mechanism,
 which is dependent just on the category $\mathcal{C}$ of constraints
 under consideration, and on the features we want to model.

\section*{Conclusions and future work}

 In this paper we have used tile logic to model the coordination and
 interaction features of logic programming.  Our approach differs from
 that of \cite{CM:ASSTS}, based on structured transition systems, by
 taking into account the computed answer substitutions instead of just
 the correct answer substitutions. In fact, in \cite{CM:ASSTS}, the
 clauses are seen as rewrite rules that can be further instantiated in
 all possible ways and the computational model of a program is a
 suitable 2-category (\ie, a special kind of double category, where
 the vertical category is discrete and thus only identities are
 allowed as observations). This means that if there exists a
 refutation for the goal $G$ with computed answer substitution
 $\theta$, then in the 2-category model we can find a refutation for
 $\theta;G$ but not necessarily one for $G$. The main advantages of
 our approach \wrt\ the one in \cite{CM:ASSTS} are a finite branching
 operational semantics and the built-in unification
 mechanism. Moreover, the drawback of using 2-categories instead of
 double categories is that the dynamic creation of fresh variables
 cannot be modeled, \ie, the variables to be used must all be present
 at the beginning of the computation.

  As noted in the Introduction, the usage of tiles emphasizes the
 duality of instantiation and contextualization of goals, allowing for
 a uniform treatment of both. In particular, while instantiation plays
 a fundamental role since it can affect the behavior of the goal,
 here contextualization (\ie, conjunction with disjoint goals) does
 not increase the distinguishing power of the semantics, and therefore
 transitions labeled with external contexts can be avoided in the
 model. In fact, each atomic goal can be studied in isolation from
 other goals and the tiles for putting a goal in any possible
 conjunction are not necessary. The reason for this absence is that
 goals cannot be conjoined in Horn clauses' heads, whereas if
 multi-headed clauses were considered, then, in general, abstract
 semantics would not turn out to be a congruence unless transitions
 for external contexts are added.  Indeed, we believe that our
 approach can be extended to other frameworks where multi-head clauses
 are allowed (see for example the \emph{generalized Horn clauses}
 of \cite{FLP:GHC} and the \textsc{chr} formalism
 \cite{Fru:CHR}), giving us the key for dealing with
 contextualization features --- dually to the instantiation via
 pullbacks considered here.

 We have also sketched some ideas for extending our approach to handle
 constraints. In this case, the constraint system and the logic
 program are modeled by two separate sets of tiles, and we have shown
 how to handle both ask and tell constraints.

 Exploiting the built-in synchronization features of tile logic, we
 are confident that our framework can be naturally extended to deal
 also with sequentialized commits (\ie, goals of the form
 $G_1;G_2;\cdots;G_k$ where the possibly non-atomic subgoals $G_i$ must be
 resolved in the order given by their indices $i$, giving the
 possibility to the user of specifying more efficient resolution
 strategies). Moreover, the higher-order version of tile logic
 presented in \cite{BM:CCDC} may find application to the modeling of
 higher-order logic programming (\eg, \emph{lambda prolog})
 \cite{Mil:LPILL,MN:HOLP}.

 Finally, let us mention that the abstractness of the unification via
 pullbacks makes the tile approach suitable for considering
 unification in equational theories rather than in term algebras. For
 example, this would allow to develop a computational model for
 rewriting logic (and hence for reduction systems on processes up to
 structural congruence) based on unification.

\section*{Acknowledgements}

 We would like to thank Paolo Baldan and Fabio Gadducci for their
 comments on a preliminary version of this paper.  We are also
 grateful to the anonymous referees for their helpful suggestions and
 comments, which allowed us to improve the presentation of the
 material.

 This research has been supported by
  CNR Integrated Project
      \emph{Progettazione e Verifica di Sistemi Eterogenei};
  by Esprit WG
      \emph{CONFER2} and \emph{COORDINA};
  and by MURST project
      \emph{TOSCA}.

\begin{thebibliography}{}

\bibitem[\protect\citename{Bernstein, }1998]{Ber:CTSOS}
Bernstein, K. (1998).
\newblock A congruence theorem for structured operational semantics of
  higher-order languages.
\newblock {\em Pages  153--164 of:} {\em Proceedings of lics'98, 13th annual
  ieee symposium on logic in computer science}.
\newblock IEEE Computer Society Press.

\bibitem[\protect\citename{Berry \& Boudol, }1992]{BB:CAM}
Berry, G., \& Boudol, G. (1992).
\newblock The chemical abstract machine.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 96}(1), 217--248.

\bibitem[\protect\citename{Best {\em et~al.}\relax, }1997]{BdBP:POSOS}
Best, E., de~Boer, S., \& Palamidessi, C. (1997).
\newblock Partial order and sos semantics for linear constraint programs.
\newblock {\em Pages  256--273 of:} {\em Proceedings of coordination'97, 2nd
  international conference on coordination languages and models}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1282.
\newblock Springer Verlag.

\bibitem[\protect\citename{Bloom {\em et~al.}\relax, }1995]{BIM:BCBT}
Bloom, B., Istrail, S., \& Meyer, A.R. (1995).
\newblock Bisimulation can't be traced.
\newblock {\em Journal of the acm}, {\bf 42}(1), 232--268.

\bibitem[\protect\citename{Bossi {\em et~al.}\relax, }1994a]{BGLM:CSLP}
Bossi, A., Gabbrielli, M., Levi, G., \& Meo, M.C. (1994a).
\newblock A compositional semantics for logic programs.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 122}(1-2), 3--47.

\bibitem[\protect\citename{Bossi {\em et~al.}\relax, }1994b]{BGLM:SSA}
Bossi, A., Gabbrielli, M., Levi, G., \& Martelli, M. (1994b).
\newblock The s-semantics approach: Theory and applications.
\newblock {\em Journal of logic programming}, {\bf 19/20}, 149--197.

\bibitem[\protect\citename{Brogi {\em et~al.}\relax, }1992]{BLM:CMTS}
Brogi, A., Lamma, E., \& Mello, P. (1992).
\newblock Compositional model-theoretic semantics for logic programs.
\newblock {\em New generation computing}, {\bf 11}(1), 1--21.

\bibitem[\protect\citename{Bruni, }1999]{Bru:TL}
Bruni, R. (1999).
\newblock {\em Tile logic for synchronized rewriting of concurrent systems}.
\newblock Ph.D. thesis, Computer Science Department, University of Pisa.

\bibitem[\protect\citename{Bruni \& Montanari, }1999]{BM:CCDC}
Bruni, R., \& Montanari, U. (1999).
\newblock Cartesian closed double categories, their lambda-notation, and the
  pi-calculus.
\newblock {\em Pages  246--265 of:} {\em Proceedings of lics'99, 14th annual
  ieee symposium on logic in computer science}.
\newblock IEEE Computer Society Press.

\bibitem[\protect\citename{Bruni \& Montanari, }2000]{BM:ZSNCCI}
Bruni, R., \& Montanari, U. (2000).
\newblock Zero-safe nets: Comparing the collective and individual token
  approaches.
\newblock {\em Inform.\ and comput.}, {\bf 156}, 46--89.

\bibitem[\protect\citename{Bruni {\em et~al.}\relax, }1998]{BMM:PTTL}
Bruni, R., Meseguer, J., \& Montanari, U. (1998).
\newblock {\em Process and term tile logic}.
\newblock Tech. rept. SRI-CSL-98-06. SRI International.
\newblock Also Technical Report TR-98-09, Computer Science Department,
  University of Pisa.

\bibitem[\protect\citename{Bruni {\em et~al.}\relax, }1999]{BMM:ETS}
Bruni, R., Meseguer, J., \& Montanari, U. (1999).
\newblock Executable tile specifications for process calculi.
\newblock {\em Pages  60--76 of:} Finance, J.-P. (ed), {\em Proceedings of
  fase'99, fundamental approaches to software engineering}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1577.
\newblock Springer Verlag.

\bibitem[\protect\citename{Bruni {\em et~al.}\relax, }2000a]{BFMM:BC}
Bruni, R., de~Frutos-Escrig, D., Mart\'\i-Oliet, N., \& Montanari, U. (2000a).
\newblock Bisimilarity congruences for open terms and term graphs via tile
  logic.
\newblock {\em Pages  259--274 of:} Palamidessi, C. (ed), {\em Proceedings of
  concur 2000, 11th international conference on concurrency theory}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1877.
\newblock Springer Verlag.

\bibitem[\protect\citename{Bruni {\em et~al.}\relax, }2000b]{BMS:OES}
Bruni, R., Montanari, U., \& Sassone, V. (2000b).
\newblock Open ended systems, dynamic bisimulation and tile logic.
\newblock {\em Pages  440--456 of:} van Leeuwen, J., Watanabe, O., Hagiya, M.,
  Mosses, P.D., \& Ito, T. (eds), {\em Proceedings of ifip tcs 2000, ifip int.
  conf. on theoretical computer science}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1872.
\newblock Springer Verlag.

\bibitem[\protect\citename{Bruni {\em et~al.}\relax, }2001]{BMM:SMCDC}
Bruni, R., Meseguer, J., \& Montanari, U. (2001).
\newblock Symmetric monoidal and cartesian double categories as a semantic
  framework for tile logic.
\newblock {\em Math.\ struct.\ in comput.\ sci.}
\newblock To appear.

\bibitem[\protect\citename{Burstall \& Rydeheard, }1985]{BR:CUA}
Burstall, R.M., \& Rydeheard, D.E. (1985).
\newblock A categorical unification algorithm.
\newblock {\em Pages  493--505 of:} Abramsky, S., Pitt, D., Poigne, A., \&
  Rydeheard, D. (eds), {\em Proceedings of workshop on category theory and
  computer programming}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 240.
\newblock Springer Verlag.

\bibitem[\protect\citename{Cattani {\em et~al.}\relax, }2000]{CLM:CECAG}
Cattani, G.L., Leifer, J.J., \& Milner, R. (2000).
\newblock {\em Contexts and embeddings for a class of action graphs}.
\newblock Tech. rept. 496. Computer Laboratory, University of Cambridge.

\bibitem[\protect\citename{Corradini \& Montanari, }1992]{CM:ASSTS}
Corradini, A., \& Montanari, U. (1992).
\newblock An algebraic semantics for structured transition systems and its
  application to logic programs.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 103}, 51--106.

\bibitem[\protect\citename{De~Nicola \& Hennessy, }1984]{dNH:TEP}
De~Nicola, R., \& Hennessy, M. (1984).
\newblock Testing equivalences for processes.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 34}, 83--133.

\bibitem[\protect\citename{De~Simone, }1985]{DeS:HLSD}
De~Simone, R. (1985).
\newblock Higher level synchronizing devices in {MEIJE}--{SCCS}.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 37}, 245--267.

\bibitem[\protect\citename{Ehresmann, }1963a]{Ehr:CS}
Ehresmann, E. (1963a).
\newblock Cat\'egories structur\`ees: {I}--{II}.
\newblock {\em Annales \'ecole normal superieur}, {\bf 80}, 349--426.

\bibitem[\protect\citename{Ehresmann, }1963b]{Ehr:CS2}
Ehresmann, E. (1963b).
\newblock Cat\'egories structur\`ees: {III}.
\newblock {\em Cahiers de topologie ed g\'eom\'etrie diff\'erentielle}, {\bf
  5}.

\bibitem[\protect\citename{Emden \& Kowalski, }1976]{EK:SPLPL}
Emden, M.H.~van, \& Kowalski, R.A. (1976).
\newblock The semantics of predicate logic as a programming language.
\newblock {\em Journal of the acm}, {\bf 23}(4), 733--742.

\bibitem[\protect\citename{Falaschi {\em et~al.}\relax, }1984]{FLP:GHC}
Falaschi, M., Levi, G., \& Palamidessi, C. (1984).
\newblock A synchronization logic: Axiomatics and formal semantics of
  generalized horn clauses.
\newblock {\em Information and control}, {\bf 60}(1-3), 36--69.

\bibitem[\protect\citename{Falaschi {\em et~al.}\relax, }1989]{FLMP:DMOBLL}
Falaschi, M., Levi, G., Martelli, M., \& Palamidessi, C. (1989).
\newblock Declarative modeling of the operational behavior of logic languages.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 69}(3), 289--318.

\bibitem[\protect\citename{Ferrari \& Montanari, }2000]{FM:TFLMS}
Ferrari, G.L., \& Montanari, U. (2000).
\newblock Tile formats for located and mobile systems.
\newblock {\em Inform.\ and comput.}, {\bf 156}, 173--235.

\bibitem[\protect\citename{Fr\"uhwirth, }1995]{Fru:CHR}
Fr\"uhwirth, T.W. (1995).
\newblock Constraint handling rules.
\newblock {\em Pages  90--107 of:} Podelski, A. (ed), {\em Constraint
  {P}rogramming: {B}asics and {T}rends}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 910.
\newblock Springer Verlag.

\bibitem[\protect\citename{Gadducci \& Montanari, }1996]{GM:RRCCS}
Gadducci, F., \& Montanari, U. (1996).
\newblock Rewriting rules and {CCS}.
\newblock  {\em Proceedings of wrla'96, 1st workshop on rewriting logic and its
  applications}.
\newblock Elect.\ Notes in Th.\ Comput.\ Sci., vol. 4.
\newblock Elsevier Science.

\bibitem[\protect\citename{Gadducci \& Montanari, }2000]{GM:TM}
Gadducci, F., \& Montanari, U. (2000).
\newblock The tile model.
\newblock  Plotkin, G., Stirling, C., \& Tofte, M. (eds), {\em Proof, language
  and interaction: Essays in honour of {R}obin {M}ilner}.
\newblock MIT Press.
\newblock Also Technical Report TR-27/96, Dipartimento di Informatica,
  Universit\`a di Pisa, 1996.

\bibitem[\protect\citename{Gaifman \& Shapiro, }1989]{GS:FACS}
Gaifman, H., \& Shapiro, E. (1989).
\newblock Fully abstract compositional semantics for logic programs.
\newblock {\em Pages  134--142 of:} {\em Proceedings of popl'89}.
\newblock ACM.

\bibitem[\protect\citename{Goguen, }1989]{Gog:WIU}
Goguen, J. (1989).
\newblock What is unification? a categorical view of substitution, equation and
  solution.
\newblock {\em Pages  217--261 of:} Nivat, M., \& A{\"{\i}}t-Kaci, H. (eds),
  {\em Resolution of equations in algebraic structures}.
\newblock Academic Press.

\bibitem[\protect\citename{Groote \& Vaandrager, }1992]{GV:SOSBC}
Groote, J.F., \& Vaandrager, F. (1992).
\newblock Structured operational semantics and bisimulation as a congruence.
\newblock {\em Inform.\ and comput.}, {\bf 100}, 202--260.

\bibitem[\protect\citename{Jaffar \& Maher, }1994]{JM:CLPS}
Jaffar, J., \& Maher, M.J. (1994).
\newblock Constraint logic programming: A survey.
\newblock {\em Journal of logic programming}, {\bf 19/20}, 503--581.

\bibitem[\protect\citename{Larsen \& Xinxin, }1990]{LX:CTOSC}
Larsen, K.G., \& Xinxin, L. (1990).
\newblock Compositionality through an operational semantics of contexts.
\newblock {\em Pages  526--539 of:} Paterson, M.S. (ed), {\em Proceedings of
  icalp'90, 17th international colloquium on automata, languages and
  programming}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 443.
\newblock Springer Verlag.

\bibitem[\protect\citename{Lawvere, }1963]{Law:FSAT}
Lawvere, F.W. (1963).
\newblock Functorial semantics of algebraic theories.
\newblock {\em Proc. national academy of science}, {\bf 50}, 869--872.

\bibitem[\protect\citename{Leifer \& Milner, }2000]{LM:DBCRS}
Leifer, J.J., \& Milner, R. (2000).
\newblock Deriving bisimulation congruences for reactive systems.
\newblock {\em Pages  243--258 of:} Palamidessi, C. (ed), {\em Proceedings of
  concur 2000, 11th international conference on concurrency theory}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1877.
\newblock Springer Verlag.

\bibitem[\protect\citename{Lloyd, }1987]{Llo:FLP}
Lloyd, J.W. (1987).
\newblock {\em Foundations of logic programming}.
\newblock Springer Verlag.

\bibitem[\protect\citename{MacLane, }1971]{Mac:CWM}
MacLane, S. (1971).
\newblock {\em Categories for the working mathematician}.
\newblock Springer Verlag.

\bibitem[\protect\citename{Mancarella \& Pedreschi, }1987]{MP:ALP}
Mancarella, P., \& Pedreschi, D. (1987).
\newblock An algebra of logic programs.
\newblock {\em Pages  1006--1023 of:} R.A., Kowalski, \& A., Bowen~K. (eds),
  {\em Proceedings of iclp'88, 5th international conference on logic
  programming}.
\newblock MIT Press.

\bibitem[\protect\citename{Marriott \& Stuckey, }1998]{MS:PCI}
Marriott, K., \& Stuckey, P.J. (1998).
\newblock {\em Programming with constraints: an introduction}.
\newblock MIT Press.

\bibitem[\protect\citename{Meseguer, }1992]{Mes:CRL}
Meseguer, J. (1992).
\newblock Conditional rewriting logic as a unified model of concurrency.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 96}, 73--155.

\bibitem[\protect\citename{Meseguer \& Montanari, }1998]{MM:TLRL}
Meseguer, J., \& Montanari, U. (1998).
\newblock Mapping tile logic into rewriting logic.
\newblock {\em Pages  62--91 of:} Parisi-Presicce, F. (ed), {\em Proceedings of
  wadt'97, 12th workshop on recent trends in algebraic development techniques}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1376.
\newblock Springer Verlag.

\bibitem[\protect\citename{Miller, }1995]{Mil:LPILL}
Miller, D. (1995).
\newblock {\em lambda prolog: An introduction to the language and its logic}.
\newblock Unpublished. Available at
  \url{http://www.cse.psu.edu/~dale/lProlog/docs.html}.

\bibitem[\protect\citename{Miller \& Nadathur, }1998]{MN:HOLP}
Miller, D., \& Nadathur, G. (1998).
\newblock Higher-order logic programming.
\newblock {\em Pages  499--590 of:} Gabbay, D.M., Hogger, C.J., \& Robinson,
  J.A. (eds), {\em Handbook of logics for artificial intelligence and logic
  programming},  vol. 5.
\newblock Clarendon Press.

\bibitem[\protect\citename{Milner, }1980]{Mil:CCS}
Milner, R. (1980).
\newblock {\em A {C}alculus of {C}ommunicating {S}ystems}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 92.
\newblock Springer Verlag.

\bibitem[\protect\citename{Milner, }1992]{Mil:PPC}
Milner, R. (1992).
\newblock The polyadic pi-calculus (abstract).
\newblock {\em Page ~1 of:} Cleaveland, R. (ed), {\em Proceedings of concur
  '92, 3rd international conference on concurrency theory}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 630.
\newblock Springer Verlag.

\bibitem[\protect\citename{Milner, }1996]{Mil:CFI}
Milner, R. (1996).
\newblock Calculi for interaction.
\newblock {\em Acta inform.}, {\bf 33}(8), 707--737.

\bibitem[\protect\citename{Montanari \& Sassone, }1992]{MS:DCPB}
Montanari, U., \& Sassone, V. (1992).
\newblock Dynamic congruence vs. progressing bisimulation for {CCS}.
\newblock {\em Fundamenta informaticae}, {\bf 16}, 171--196.

\bibitem[\protect\citename{Montanari \& Talcott, }1998]{MT:APA}
Montanari, U., \& Talcott, C. (1998).
\newblock Can actors and $\pi$-agents live together?
\newblock  {\em Proceedings of hoots'98, 2nd workshop on higher order
  operational techniques in semantics}.
\newblock Elect.\ Notes in Th.\ Comput.\ Sci., vol. 10.
\newblock Elsevier Science.

\bibitem[\protect\citename{Park, }1981]{Par:CAIS}
Park, D. (1981).
\newblock Concurrency and automata on infinite sequences.
\newblock {\em Pages  167--183 of:} {\em Proceedings of fifth g-i conference}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 104.
\newblock Springer Verlag.

\bibitem[\protect\citename{Plotkin, }1981]{Plo:SAOS}
Plotkin, G. (1981).
\newblock {\em A structural approach to operational semantics}.
\newblock Tech. rept. DAIMI FN-19. Aarhus University, Computer Science
  Department.

\bibitem[\protect\citename{Rensink, }2000]{Ren:BOT}
Rensink, A. (2000).
\newblock Bisimilarity of open terms.
\newblock {\em Inform.\ and comput.}, {\bf 156}, 345--385.

\bibitem[\protect\citename{Saraswat, }1989]{Sar:CC}
Saraswat, V.A. (1989).
\newblock {\em Concurrent constraint logic programming}.
\newblock Ph.D. thesis, Carnegie-Mellon University.

\bibitem[\protect\citename{Sewell, }1998]{Sew:RRBC}
Sewell, P. (1998).
\newblock From rewrite rules to bisimulation congruences.
\newblock {\em Pages  269--284 of:} Sangiorgi, D., \& de~Simone, R. (eds), {\em
  Proceedings of concur'98}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1466.
\newblock Springer Verlag.

\end{thebibliography}

\end{document}

xy.tex
%% xy.tex from $Id: xy.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
%%
%% Basic Xy-pictures: Xy-pic bootstrap and kernel macros.
%% Copyright (c) 1991-1999 Kristoffer H. Rose <krisrose@ens-lyon.fr>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% Copyright (c) 1991-1999 Kristoffer H. Rose <krisrose@ens-lyon.fr>
%%
%% 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\gdef#1}
\xywarnifdefined\xylet@ \gdef\xylet@#1{\xywarnifdefined#1\global\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
 \catcode 35 6 \catcode 36 3 \catcode 38 4
 \catcode 43 12 \catcode 45 12 \catcode 46 12 \catcode 47 12
 \catcode 60 12 \catcode 61 12 \catcode 62 12
 \catcode 64 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`\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
\xydef@\testAND@{{\aftergroup\ifx 
 \addAND@\ifx\next\addFalse@\else\addTrue@\fi}}
\xydef@\addFalse@{\aftergroup\iffalse}
\xydef@\addTrue@{\aftergroup\iftrue}
\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.7 $}
\xylet@\xyversion=\next
\edef\next{\stripRCS$Date: 1999/02/16 15:12:50 $}
\xylet@\xydate=\next
\xydef@\Xygreet@{%
 \W@{}%
 \W@{ Xy-pic version \xyversion\space<\xydate>}%
 \W@{ Copyright (c) 1991-1998 by Kristoffer H. Rose <krisrose@ens-lyon.fr>}%
 \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}}}
\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=10
 \W@{}\W@{Xy-pic Warning: #1\xytracelineno@.}\W@{}}}
\xydef@\xyerror@#1#2{\if\inxy@\xy@{ERROR #1}{}\fi
 {\def\2{#2}\newlinechar=10
 \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=10
 \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, krisrose@ens-lyon.fr.}%
 \errmessage{Xy-pic BUG: #1 -- notify krisrose@ens-lyon.fr.}}}
\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 \else
 \DN@{\xyinputorelse@@{#1}{\xyinputorelse@@{#1.doc}{#2}}}%
 \fi \next@}
\xydef@\xyinputorelse@@#1#2{\openin\xyread@=#1
 \ifeof\xyread@ \DN@{#2}\else \DN@{\closein\xyread@\input#1 }\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@
 \advance\B@\ifdim\B@<\z@-\fi 16sp \divide\B@\KK@
 \else
 \advance\B@\ifdim\B@<\z@-\fi 512sp \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@
 \advance\B@\ifdim\B@<\z@-\fi 128sp \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@\change@oxy@#1{\let\oxy@=#1\relax
}
\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@ \change@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@{%
 \saveXyStyle@ \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
 \mathsurround=\z@
 \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@
 \noexpand\recoverXyStyle@ \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
}
\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@\preconnect@#1#2{\setupDirection@ \enter@{\cfromthec@}%
 \global\setbox\lastobjectbox@=\object#1{#2}\leave@ \connectStore@
 \ifInvisible@ \Connect@@ \else \Invisible@true\Connect@@\Invisible@false \fi}
\xynew@{box}\connectobjectbox@@
\xylet@\connectDrop@@=\empty
\xylet@\connectpreXY@style@=\empty
\xylet@\connectpostXY@style@=\empty
\xylet@\connectRest@@=\empty
\xydef@\connectStore@{%
 \global\setbox\connectobjectbox@@=\copy\lastobjectbox@
 \let\connectDrop@@=\Drop@@
 \let\connectpreXY@style@ =\preXY@style@ 
 \let\connectpostXY@style@=\postXY@style@
 \xdef\connectRest@@{%
 \def\noexpand\Upness@{\Upness@}%
 \def\noexpand\Leftness@{\Leftness@}%
 \ifInvisible@ \noexpand\Invisible@true \else \noexpand\Invisible@false \fi
 \ifHidden@ \noexpand\Hidden@true \else \noexpand\Hidden@false \fi}}
\xydef@\connectRestore@{%
 \ifvbox\connectobjectbox@@
 \setbox\lastobjectbox@=\copy\voidb@x
 \else
 \global\setbox\lastobjectbox@=\copy\connectobjectbox@@
 \fi
 \let\Drop@@=\connectDrop@@
 \global\let\preXY@style@ =\connectpreXY@style@ 
 \global\let\postXY@style@=\connectpostXY@style@
 \connectRest@@}
\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@ \change@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@ \change@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\ifx @\next\DN@ @##1##{%
\xywarning@{Impossible @ (letter) should not be here!!}
 \OBJECT@@{\dir##1}}%
 \else \let\next@=\OBJECT@direction
 \fi\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}%
 \gdef\preXY@style@{}\gdef\postXY@style@{}%
 \def\Drop@@{\styledboxz@}\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}
\def\checkZeroEdge@{%
 \DN@{}%
 \ifdim\zz@\L@c \ifdim\zz@\R@c \ifdim\zz@\U@c \ifdim\zz@\D@c
 \DN@{\Edge@c={\zeroEdge}}\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@@{\styledboxz@}
\xydef@\Connect@@{}
\xydef@\objectbox#1{\hbox{$\m@th\objectstyle{#1}$}}
\xylet@\objectstyle=\textstyle
\xydef@\object{\hbox\bgroup\resetStyle@\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
 \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\U@p\D@c \centerobject@
 \ifdim\L@c>\D@c
 \advance\R@c\L@c \L@c=.5\U@c \advance\L@c.5\D@c \advance\R@c-\L@c \fi
 \advance\U@p-\D@c}
\xydefcsname@{shape [l]}{\advance\U@p\D@c \centerobject@
 \ifdim\L@c>\D@c
 \advance\L@c\R@c \R@c=.5\U@c \advance\R@c.5\D@c \advance\L@c-\R@c \fi
 \advance\U@p-\D@c}
\xydefcsname@{shape [u]}{\advance\U@p\D@c \centerobject@
 \ifdim\D@c>\L@c
 \advance\U@c\D@c \D@c=.5\L@c \advance\D@c.5\R@c \advance\U@c-\D@c \fi
 \advance\U@p-\D@c}
\xydefcsname@{shape [d]}{\advance\U@p\D@c \centerobject@
 \ifdim\D@c>\L@c
 \advance\D@c\U@c \U@c=.5\L@c \advance\U@c.5\R@c \advance\D@c-\U@c \fi
 \advance\U@p-\D@c}
\xydefcsname@{shape [c]}{\advance\U@p\D@c \centerobject@ \advance\U@p-\D@c}
\xydef@\centerobject@{%
 \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 [Outer]}{\the\Edge@c5\relax}%
\xydefcsname@{shape [Inner]}{\the\Edge@c4\relax}%
\xydefcsname@{shape [o]}{\Edge@c={\circleEdge}\the\Edge@c5\relax 
 \Edge@c={\circleEdge}\def\prevEdge@@{\circleEdge}}
\xydefcsname@{shape [.]}{\czeroEdge@}
\def\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% Delete this: \expandafter\addtotoks@\expandafter{\next{#2}}%
 \DN@{\next{#2}\xyFN@\OBJECT@}%
 \fi
 \else
\expandafter\addtotoks@\expandafter{\next{#2}}\DN@{\next{#2}\xyFN@\OBJECT@}%
 \fi \next@}
\xydef@\preXY@style@{}
\xydef@\postXY@style@{}
\xydef@\resetStyle@{\gdef\preXY@style@{}\gdef\postXY@style@{}}
\xynew@{toks}{\styletoks@}
\xydef@\addtostyletoks@#1{%
 \expandafter\styletoks@\expandafter{\the\styletoks@#1}}
\xydef@\styledboxz@{%
 \xypre@Style@@
 \boxz@
 \xypost@Style@@}
\xydef@\xypre@Style@{\styletoks@={}\saveXyStyle@\preXY@style@
 \expandafter\DN@\expandafter{\the\styletoks@}%
 \ifx\next@\empty \DN@{\let\xypre@Style@@=\relax 
 \let\xypost@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@\xypre@skipStyle@#1\xypost@Style@@{#1\relax 
 \let\xypre@Style@@=\xypre@Style@ }
\xydef@\xydoprestyles@@{\literal@}
\xydef@\xydopoststyles@@{\literal@}
\xylet@\xydoprestyles@=\xydoprestyles@@
\xylet@\xydopoststyles@=\xydopoststyles@@
\xydef@\modXYstyle@{%
 \ifx\xy@style@\empty\resetStyle@\fi \checkXyStyle@
 \expandafter\expandafter\expandafter\DN@
 \expandafter\expandafter\expandafter{\preXYstyle@@}%
 \ifx\next@\empty\else\DN@{\modXYstyle@@}\fi \next@ }
\xydef@\modXYstyle@@{%
 \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}%
 \expandafter\next@\expandafter{\preStyle@@}%
 \DN@##1{\expandafter\gdef\expandafter\preXY@style@\expandafter{%
 \preXY@style@ ##1}}\expandafter\next@\expandafter{\tmp@}%
 \DN@##1{\expandafter\def\expandafter\tmp@\expandafter{##1}}%
 \expandafter\next@\expandafter{\postStyle@@}%
 \DN@##1{\expandafter\gdef\expandafter\postXY@style@\expandafter{%
 \tmp@ ##1}}\expandafter\next@\expandafter{\postXY@style@}}
\xydef@\xy@style@{}
\xydef@\checkXyStyle@{\ifx\xy@style@\empty\resetStyle@\fi
 \let\xy@style@=\relax}
\xydef@\preStyle@@{}
\xydef@\postStyle@@{}
\xydef@\preXYstyle@@{\relax}
\xydef@\loadxystyle@{%
 \let\xypre@Style@@=\xypre@Style@ \def\preXYstyle@@{\preStyle@@}}
\loadxystyle@
\xydef@\Unloadstyle@{%
 \let\xypre@Style@@=\relax \let\xypost@Style@@=\relax
 \def\preXYstyle@@{\relax}}
\xydefcsname@{shape [=...]}#1{\checkXyStyle@ \addtotoks@{\xynamestyle@{#1}}}
\xydef@\xynamestyle@#1{\checkXyStyle@
 \expandafter\DNii@\expandafter{\csname shape [#1]\endcsname}%
 \expandafter\ifx\nextii@\relax
 \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@\prevXypreStyle@@{}
\xydef@\prevXypostStyle@@{}
\xydef@\saveXyStyle@{\expandafter
 \def\expandafter\prevXypreStyle@@\expandafter{\preXY@style@}%
 \expandafter\def\expandafter\prevXypostStyle@@\expandafter{%
 \postXY@style@}}
\xydef@\recoverXyStyle@{\expandafter
 \gdef\expandafter\preXY@style@\expandafter{\prevXypreStyle@@}%
 \expandafter\gdef\expandafter\postXY@style@\expandafter{%
 \prevXypostStyle@@}}
\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}}
\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@\preconnect#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
 \xy@{\connect#1{##1}}{\expandafter\preconnect@\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{\xystatus@cp{#1}%
 \W@{#1 d=<\the\d@X,\the\d@Y>
 Direction=\the\Direction=\string(\cosDirection,\sinDirection\string)}%
 \W@{#1 base=<\the\X@origin,\the\Y@origin>+%
 <\the\X@xbase,\the\Y@xbase>x+<\the\X@ybase,\the\Y@ybase>y}%
 \W@{#1 min/max=<\the\X@min,\the\Y@min>/<\the\X@max,\the\Y@max>
 S=\the\csp@}}
\xydef@\xystatus@cp#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]
 \ifInvisible@ I\fi\ifHidden@ H\fi}%
 \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]}}
\xydef@\xystatus@c#1{%
 \W@{#1<\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]}}
\xydef@\xyquiet{\xy@\xyquiet{\let\xy@=\oxy@}}
\xydef@\xyignore#1{\xy@\xyignore{\xyignore@{#1}}\ignorespaces}
\xydef@\xyignore@#1{{\let\xy@=\xyeat@ \change@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
 \outlines@@\writeoutline@\writeoutline@}
\xydef@\xysaving@{\let\xy@=\xysave@ \change@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 \outlines@@\relax\readoutline@
 \else \def\xyrecompile@@{recompiling to}\endinput \fi
 \else \def\xyrecompile@@{Xy-pic version change - recompiling}\endinput \fi}
\xydef@\xyendcompiled{\let\xyrecompile@@=\relax \xyuncatcodes\endinput}
\xydef@\CompileFixPoint#1{%
 \expandafter\ifx\csname#1FIX@@\endcsname\relax
 \expandafter\xdef\csname#1FIX@@\endcsname{\xycompileno@@}%
 \else
 \xdef\xycompileno@@{\csname#1FIX@@\endcsname}\fi}
\xydef@\outlines@no#1#2{}
\xydef@\outlines@make#1#2{#1}
\xydef@\outlines@only#1#2{#2}
\xylet@\outlines@@=\outlines@no
\xylet@\writeoutline@@=\relax
\xylet@\readoutline@@=\relax
\xydef@\MakeOutlines{\let\outlines@@=\outlines@make}
\xydef@\OnlyOutlines{\xywarning@{Compiled pictures only shown as outlines}%
 \let\outlines@@=\outlines@only}
\xydef@\ShowOutlines{\let\readoutline@@=\typesetoutline@}
\xydef@\NoOutlines{\let\outlines@@=\outlines@no}
\xydef@\writeoutline@{%
 \DN@{\immediate\openout\xywrite@=}\expandafter\next@\compilename@@.xyd
 \immediate\write\xywrite@{\xycomment@\space\compilename@@.xyd}
 \immediate\write\xywrite@{%
 \string\X@min=\the\X@min \string\X@max=\the\X@max
 \string\Y@min=\the\Y@min \string\Y@max=\the\Y@max \string\relax}%
 \writeoutline@@
 \immediate\closeout\xywrite@}
\xynew@{if}\ifoutlineread@
\xydef@\readoutline@{\outlineread@true
 \expandafter\xyinputorelse@@\expandafter{\compilename@@.xyd}%
 {\def\xyrecompile@@{outline missing - recompiling to}\outlineread@false}%
 \ifoutlineread@ \readoutline@@
 \writeoutline@\expandafter\xyendcompiled\fi}
\xydef@\typesetoutline@{%
 \xy@@{\czeroEdge@ \U@p=\z@ \D@p=\z@ \L@p=\z@ \R@p=\z@ \Edge@p={\zeroEdge}%
 \X@p=\X@min \Y@p=\Y@min \X@c=\X@min \Y@c=\Y@max \connect@\dir{.}%
 \X@p=\X@c \Y@p=\Y@c \X@c=\X@max \Y@c=\Y@max \connect@\dir{.}%
 \X@p=\X@c \Y@p=\Y@c \X@c=\X@max \Y@c=\Y@min \connect@\dir{.}%
 \X@p=\X@c \Y@p=\Y@c \X@c=\X@min \Y@c=\Y@min \connect@\dir{.}}}
\message{kernel objects:}
\message{directionals,}
\xydef@\dir{\hbox\bgroup\xyFN@\dir@i}
\xydef@\dir@i{\ifx *\next \DN@*{\resetStyle@\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@
 \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}%
 \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@@{\styledboxz@}\def\Connect@@{\solid@}}
\xydef@\line@@{{\xydashfont\SemiDirectionChar\/}}
\xydef@\solid@{%
 \checkXy@rules@\solidhrule@\solidvrule@{\straight@\solidSpread@}}
\xydef@\checkXy@rules@#1#2#3{%
 \dimen@=\Y@c \advance\dimen@-\Y@p
 \ifjusthvtest@.05pt>\ifdim\dimen@<\z@-\fi\dimen@ \DN@{#1}%
 \else \dimen@=\X@c \advance\dimen@-\X@p
 \ifjusthvtest@.05pt>\ifdim\dimen@<\z@-\fi\dimen@ \DN@{#2}%
 \else \DN@{#3}\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@@ \solidvrule@typeset \ifHidden@\else\noinsert@\fi
 \solidvrule@pre}
\xydef@\solidvrule@pre{%
 \def\Cbreak@@{%
 \connectRestore@ \swap@\lastbreak@@\swap@
 \solidvrule@typeset \edef\lastbreak@@{\cfromthec@}\Creset@@}%
 \def\Clast@@{%
 \connectRestore@ \Creset@@\swap@\lastbreak@@\swap@
 \solidvrule@typeset \Creset@@ \edef\lastbreak@@{\cfromthep@}}%
}
\xydef@\solidvrule@typeset{%
 \ifInvisible@ \let\next@=\relax \else \let\next@=\solidvrule@typeset@ \fi
 \checkoverlap@@ \next@}
\xydef@\solidvrule@typeset@{{%
 \advance\X@c\X@p \X@c=.5\X@c \X@p=\X@c
 \advance\X@c-.5\xydashw@ \advance\X@p.5\xydashw@
 \ifdim\Y@c<\Y@p \advance\Y@c\U@c \advance\Y@p-\D@p
 \else \swapdimen@\Y@c\Y@p \advance\Y@c\U@p \advance\Y@p-\D@c \fi
 \Droprule@}}
\xydef@\solidhrule@{\no@@ \solidhrule@typeset \ifHidden@\else\noinsert@\fi
 \solidhrule@pre}
\xydef@\solidhrule@pre{%
 \def\Cbreak@@{%
 \connectRestore@ \swap@\lastbreak@@\swap@
 \solidhrule@typeset \edef\lastbreak@@{\cfromthec@}\Creset@@}%
 \def\Clast@@{%
 \connectRestore@ \Creset@@\swap@\lastbreak@@\swap@
 \solidhrule@typeset \Creset@@ \edef\lastbreak@@{\cfromthep@}}%
}
\xydef@\solidhrule@typeset{%
 \ifInvisible@ \let\next@=\relax \else \let\next@=\solidhrule@typeset@ \fi
 \checkoverlap@@ \next@}
\xydef@\solidhrule@typeset@{{%
 \ifdim\X@c<\X@p \advance\X@c\R@c \advance\X@p-\L@p
 \else \swapdimen@\X@c\X@p \advance\X@c\R@p \advance\X@p-\L@c \fi
 \advance\Y@c\Y@p \Y@c=.5\Y@c \Y@p=\Y@c
 \advance\Y@c-.5\xydashw@ \advance\Y@p.5\xydashw@
 \Droprule@}}
\xydef@\Droprule@{\advance\X@p-\X@c
 \setboxz@h{\kern\X@c \vrule width\X@p depth-\Y@c height\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
 \def\Leftness@{.5}\def\Upness@{.5}\ctipEdge@
 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@{#2}}}}
\xydef@\dottedSpread@#1{%
 \dimen@=#1\relax \DN@{\A@=2\A@ \B@=2\B@ \dottedSpread@i}%
 \A@=\sd@X\cosDirection\dimen@ \B@=\sd@Y\sinDirection\dimen@
 \dimen@=\A@ \advance\dimen@\B@
 \dimen@ii=\sd@X\d@X \advance\dimen@ii\sd@Y\d@Y
 \ifdim\dimen@>\dimen@ii \DN@{\count@@=\z@}\fi
 \next@}
\xydef@\dottedSpread@i{%
 \global\setbox8=\hbox to\A@{\hss
 \kern.5\A@\box\lastobjectbox@\kern.5\A@\hss}\dp8=.5\B@ \ht8=.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 \dimen@=\sd@Y\d@Y
 \ifdim\zz@\B@\else \divide\dimen@\B@ \fi \count@@=\dimen@
 \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}%
 \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\styledboxz@}\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@
 \setboxz@h{\setbox2=\hbox{\kern\A@\raise\B@\copy\z@}%
 \dp2=\z@ \ht2=\z@ \wd2=\z@ \box2
 \setbox2=\hbox{\kern-\A@\raise-\B@ \noexpand\boxz@}%
 \dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 }%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \noexpand\styledboxz@}}
\xydef@\triple@#1{\edef\Drop@@{\dimen@=#1\relax
 \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
 \setboxz@h{\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@ \noexpand\boxz@}%
 \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ \noexpand\styledboxz@}}
\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@
 \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\styledboxz@}\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}%
 \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\styledboxz@}\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{<}}{\composite@{}{:(-1,0)\dir3{>}}}
\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}%
 \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\styledboxz@}\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@{dir1{||}}{\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@}}
\xyletcsnamecsname@{dir0{||}}{dir{}}
\xyletcsnamecsname@{dir{||}}{dir1{||}}
\xydefcsname@{dir1{>|}}{\shiftdir@\stopper@\z@ \tip@}
\xydefcsname@{dir2{>|}}{\composite@{}{\dir2{>}*\dir2{|}}}
\xydefcsname@{dir3{>|}}{\composite@{}{\dir3{>}*\dir3{|}}}
\xyletcsnamecsname@{dir0{>|}}{dir{}}
\xyletcsnamecsname@{dir{>|}}{dir1{>|}}
\xydefcsname@{dir1{>>|}}{\shiftdir@\stopper@\z@ \shiftdir@\tip@\tipjot@ \tip@}
\xydefcsname@{dir2{>>|}}{\composite@{}{h!/\tipjot@/\dir2{>}*\dir2{>}*\dir2{|}}}
\xydefcsname@{dir3{>>|}}{\composite@{}{h!/\tipjot@/\dir3{>}*\dir3{>}*\dir3{|}}}
\xyletcsnamecsname@{dir0{>>|}}{dir{}}
\xyletcsnamecsname@{dir{>>|}}{dir1{>>|}}
\xydefcsname@{dir1{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \tip@}
\xydefcsname@{dir2{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \Tip@}
\xydefcsname@{dir3{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \Ttip@}
\xyletcsnamecsname@{dir0{|<}}{dir{}}
\xyletcsnamecsname@{dir{|<}}{dir1{|<}}
\xydefcsname@{dir1{|<<}}{\reverseDirection@
 \shiftdir@\stopper@\z@ \shiftdir@\tip@\tipjot@ \tip@}
\xydefcsname@{dir2{|<<}}{%
 \composite@{}{h!/-\tipjot@/\dir2{<}*\dir2{<}*\dir2{|}}}
\xydefcsname@{dir3{|<<}}{%
 \composite@{}{h!/-\tipjot@/\dir3{<}*\dir3{<}*\dir3{|}}}
\xyletcsnamecsname@{dir0{|<<}}{dir{}}
\xyletcsnamecsname@{dir{|<<}}{dir1{|<<}}
\xydefcsname@{dir1{|-}}{\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{|-}}{dir1{|-}}
\xyletcsnamecsname@{dir{|=}}{dir2{|-}}
\xydefcsname@{dir{+}}{%
 \DN@##1{\composite@{}{##10\dir{|}*!C##10\dir{-}}}\addEQ@\next@}
\xyletcsnamecsname@{dir0{+}}{dir{}}
\xydefcsname@{dir{x}}{\vDirection@(1,1)\jot
 \DN@##1{\composite@{}{##10\dir{|}*!C##10\dir{-}}}\addEQ@\next@}
\xyletcsnamecsname@{dir0{x}}{dir{}}
\xydefcsname@{dir{/}}{\vDirection@(1,-.3)\jot \stopper@}
\xyletcsnamecsname@{dir0{/}}{dir{}}
\xydefcsname@{dir{//}}{\vDirection@(1,-.3)\jot
 \shiftdir@\stopper@\xydashh@ \stopper@}
\xyletcsnamecsname@{dir0{//}}{dir{}}
\xydefcsname@{dir{*}}{\solidpoint@}
\xydef@\solidpoint@{%
 \pointlike@{\kern-1.8pt\lower1.8pt\hbox{$\scriptstyle\bullet$}}\jot}
\xyletcsnamecsname@{dir0{*}}{dir{}}
\xydefcsname@{dir{o}}{\hollowpoint@}
\xydef@\hollowpoint@{%
 \pointlike@{\kern-1.8pt\lower1.8pt\hbox{$\scriptstyle\circ$}}\jot}
\xyletcsnamecsname@{dir0{o}}{dir{}}
\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@@{\styledboxz@}\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{\styledboxz@}\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\leavevmode#1\crcr}}}
\message{options;}
\xylet@\xyoption@@=\relax
\xydef@\xyoption#1{\DN@{#1}\edef\next@{\codeof\next@}%
 \csname xyeveryrequest@\next@ @\endcsname
 \xyinputorelse@{xy#1}{\xyoption@truncated#1@@@@@@@@@,#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@#8,#9@{%
 \DN@{#7}\ifx\next@\empty \DN@##1##2{##2}\else\let\next@=\xyinputorelse@ \fi
 \next@{xy#1#2#3#4#5#6}%
 {\DN@{#1#2#3#4#5#6}\edef\next@{\codeof\next@}%
 \xyerror@{No `\next@' option}{%
Your \xyoption{#9} request could not be granted: the required^^J%
file `xy#9.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@Y{-}%
 \edef\sd@X{\ifdim\X@c<\X@p-\else+\fi}%
 \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{+}%
 \edef\sd@Y{\ifdim\Y@c<\Y@p-\else+\fi}%
 \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@Y{+}%
 \edef\sd@X{\ifdim\X@c<\X@p-\else+\fi}%
 \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{-}%
 \edef\sd@Y{\ifdim\Y@c<\Y@p-\else+\fi}%
 \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@\ifdim\dimen@<\z@-\fi.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@\ifdim\dimen@<\z@-\fi.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 
 \advance\Direction\ifnum\Direction<\z@-\fi\@ne \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@\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\X@c
 \advance\Y@c-\Y@p \D@c=\ifdim\Y@c<\z@-\fi\Y@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@Y \U@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@\Cintercept@@{\noCintercept@@}
\xydef@\Cbreak@@{\noCbreak@@}
\xydef@\Clast@@{\noClast@@}
\xylet@\lastbreak@@=\empty
\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@\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@\noCbreak@@{\edef\lastbreak@@{\cfromthec@}}
\xydef@\noClast@@{\Creset@@ \edef\lastbreak@@{\cfromthep@}}
\xydef@\no@@{\setupDirection@ \edef\lastbreak@@{\cfromthep@}%
 \enter@{\cfromthec@\pfromthep@\DirectionfromtheDirection@}%
 \edef\Creset@@{\cfromthec@ \pfromthep@ \DirectionfromtheDirection@}%
 \edef\next@{{\sd@X}{\sd@Y}}\expandafter\straightcheckoverlap@\next@
 \setupDirection@ \the\Edge@c\z@
 \swap@\reverseDirection@\the\Edge@c\z@\swap@\reverseDirection@
 \resetDirection@
 \edef\Cshavep@@{\DirectionfromtheDirection@
 \pfromthep@\noexpand\resetDirection@}%
 \edef\Cshavec@@{\DirectionfromtheDirection@
 \cfromthec@\noexpand\resetDirection@}%
 \leave@
 \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%
 \def\Calong@@{\noCalong@@}\def\Cintercept@@{\noCintercept@@}%
 \def\Cbreak@@{\noCbreak@@}\def\Clast@@{\noClast@@}\noinsert@}
\xydef@\noinsert@{\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@}%
 \edef\lastbreak@@{\cfromthep@}%
 \edef\next@{{\sd@X}{\sd@Y}}\expandafter\straightcheckoverlap@\next@
 \setupDirection@ \the\Edge@c\z@
 \swap@\reverseDirection@\the\Edge@c\z@\swap@\reverseDirection@
 \resetDirection@
 \edef\Cshavep@@{\DirectionfromtheDirection@
 \pfromthep@\noexpand\resetDirection@}%
 \edef\Cshavec@@{\DirectionfromtheDirection@
 \cfromthec@\noexpand\resetDirection@}%
 \noinsert@
 \straight@typeset
 \def\Cbreak@@{\straightCbreak@}\def\Clast@@{\straightClast@}%
 \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%
 \def\Calong@@{\noCalong@@}\def\Cintercept@@{\noCintercept@@}%
 \Creset@@}
\xydef@\straightcheckoverlap@#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}}
\xydef@\straight@typeset{%
 \ifInvisible@ \let\next@=\relax
 \else\ifdim 1\Direction<-2\K@ \DN@{\straightv@}%
 \else\ifdim 1\Direction<\z@ \DN@{\straighth@}%
 \else\ifdim 1\Direction<2\K@ \DN@{\straightv@}%
 \else \DN@{\straighth@}%
 \fi\fi\fi\fi \checkoverlap@@ \next@}
\xylet@\nextbreak@@=\empty
\xydef@\straightCbreak@{\connectRestore@
 \edef\nextbreak@@{\cfromthec@}%
 \Creset@@ \swap@ \the\Edge@c4\enter@{\cmergethec@}\lastbreak@@ \leave@
 \swap@ \the\Edge@c4\enter@{\cmergethec@}\nextbreak@@ \leave@
 \setupDirection@
 \the\Edge@c\z@
 \swap@ \reverseDirection@ \the\Edge@c\z@ \swap@ \reverseDirection@
 \resetDirection@ \noinsert@ \straight@typeset
 \Creset@@ \let\lastbreak@@=\nextbreak@@}
\xydef@\straightClast@{\connectRestore@
 \Creset@@ \swap@ \the\Edge@c4\enter@{\cmergethec@}\lastbreak@@ \leave@
 \swap@
 \setupDirection@
 \the\Edge@c\z@
 \swap@\reverseDirection@ \the\Edge@c\z@ \swap@\reverseDirection@
 \resetDirection@ \noinsert@ \straight@typeset
 \Creset@@ \edef\lastbreak@@{\cfromthep@}}
\xydef@\straighth@{\setbox\z@=\hbox{%
 \setbox8=\copy\lastobjectbox@
 \A@=\wd8\relax \B@=\dp8\relax \advance\B@\ht8\relax
 \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-\wd8\relax\fi
 \dimen@=-\sd@X\wd8\relax
 \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@=\wd8\relax \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@ \wd8=\A@
 \kern\X@c \count@=\z@
 \loop@\ifnum\count@<\count@@ \advance\count@\@ne
 \raise\Y@c\copy8\relax \advance\Y@c\B@ \repeat@}%
 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}
\xydef@\straightv@{\setbox\z@=\vtop{%
 \setbox8=\copy\lastobjectbox@
 \A@=\wd8\relax \B@=\dp8\relax \advance\B@\ht8\relax
 \ifdim \B@=\z@ \count@@=\m@ne
 \else \dimen@=\sd@Y\d@Y \divide\dimen@\B@ \count@@=\dimen@ \fi
 \Spread@@
 \dimen@=\dp8\relax \advance\dimen@\ht8\relax
 \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@ \ht8=\B@ \dp8=\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-\wd8\relax \fi
 \null \kern-\Y@c \count@=\z@
 \loop@\ifnum\count@<\count@@ \advance\count@\@ne
 \nointerlineskip \moveright\X@c\copy8\relax \advance\X@c\A@
 \repeat@}%
 \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}
\message{ Xy-pic loaded}\xyuncatcodes \endinput

xyarrow.tex
%% xyarrow.tex from $Id: xyarrow.doc,v 3.5 1997/05/28 13:05:01 krisrose Exp $
%%
%% Xy-pic ``Arrows and Paths'' feature.
%% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.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-1997 Kristoffer H. Rose <krisrose@brics.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.5 $}%
 {Kristoffer H.~Rose}{krisrose@brics.dk}%
 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
 DK--8000 Aarhus~C}
\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\PATHbefore@@=\empty
 \let\PATHafter@@=\empty
 \let\PATHlabelsevery@@=\empty
 \let\PATHlabelsnext@@=\empty
 \let\PATHlabelslast@@=\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@\PATHfinal@}%
 \else
 \DNii@{\let\PATHfail@@=\PATH@x \xyFN@\PATH@}%
 \DN@{\expandafter\nextii@\PATHfail@@}%
 \fi\fi\fi\fi \next@}
\xylet@\PATHfail@@=\empty
\xylet@\PATHbefore@@=\empty
\xylet@\PATHafter@@=\empty
\xylet@\PATHlabelsevery@@=\empty
\xylet@\PATHlabelsnext@@=\empty
\xylet@\PATHlabelslast@@=\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\PATHbefore@@{##1}\xyFN@\PATH@}%
 \else \addLT@\ifx \next
 \addLT@\DN@##1{\xy@{~<{##1}}{}\def\PATHlabelsnext@@{##1}\xyFN@\PATH@}%
 \else \addGT@\ifx \next
 \addGT@\DN@##1{\xy@{~>{##1}}{}\def\PATHlabelslast@@{##1}\xyFN@\PATH@}%
 \else \addPLUS@\ifx \next
 \addPLUS@\DN@##1{\xy@{~+{##1}}{}\def\PATHlabelsevery@@{##1}\xyFN@\PATH@}%
 \else \ifx /\next
 \DN@/##1{\xy@{~/{##1}}{}\def\PATHafter@@{##1}\xyFN@\PATH@}%
 \else \addDASH@\ifx \next
 \xywarning@{Obsolete `-' PATH <action> translated to `='.}%
 \addDASH@\DN@##1{\xy@{~-{##1}}{}\def\PATHbefore@@{##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@}%
 \let\PATHextra@@=\empty
 \let\PATHpost@@=\empty
 \let\PATHlabelsextra@@=\relax
 \xy@@\pfromc@ \PATHafterPOS{\xyFN@\PATHsegment@}}
\xydef@\PATHfinal@{%
 \def\PATHinit@@{\PATHinitstraight@}%
 \def\PATHextra@@{\let\PATHcontinue@@=\afterPATH@}%
 \let\PATHpost@@=\empty
 \let\PATHlabelsextra@@=\PATHlabelsextralast@
 \xy@@\pfromc@ \PATHafterPOS{\xyFN@\PATHsegment@}}
\xydef@\PATHlabelsextralast@{\let\PATHlabelsextra@@=\relax
 \expandafter\xyFN@\expandafter\PATHlabels@\PATHlabelslast@@}
\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@}
\xydef@\PATHsegment@@{\PATHinit@@ \addEQ@\PATHaction@\PATHbefore@@ \PATHextra@@
 \expandafter\toks@\expandafter{\PATHlabelsnext@@}\let\PATHlabelsnext@@=\empty
 \expandafter\addtotoks@\expandafter{\PATHlabelsevery@@}%
 \expandafter\def\expandafter\PATHlabels@@\expandafter{\the\toks@}%
 \toks@={}\expandafter\xyFN@\expandafter\PATHlabels@\PATHlabels@@}
\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@=\PATHfinishsegments@ \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@\PATHfinishsegments@{%
 \ifx\PATHlabelsextra@@\relax \expandafter\PATHfinishsegments@i
 \else
 \expandafter\PATHlabelsextra@@ \fi}
\xydef@\PATHfinishsegments@i{%
 \xy@@{\Clast@@}\the\toks@ \toks@={}%
 \xy@@\setupDirection@
 \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@={}%
 \let\PATHextra@@=\empty
 \def\PATHpost@@{\xy@@\PATHpostpos@@}%
 \let\PATHlabelsextra@@=\relax
 \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{\droplabel@\belowDirection@{#1}{#2}%
 \let\afteraliases@@=\empty \xyFN@\PATHlabelalias@}
\xydef@\PATHlabelbelow@#1#2{\droplabel@\aboveDirection@{#1}{#2}%
 \let\afteraliases@@=\empty \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@}}
\xydef@\PATHlabelbreak@#1#2{%
 \DN@{#1}\ifx\next@\empty \drop\labelbox{#2}\else \drop#1{#2}\fi
 \def\afteraliases@@{\xy@@\Cbreak@@}\xyFN@\PATHlabelalias@}
\xylet@\labelmargin@=\objectmargin@
\xydef@\labelmargin{\afterADDOP{\Addop@@\labelmargin@}}
\xydef@\hole{\hbox{\dimen@=\objectmargin@ \kern2\dimen@
 \vrule height\dimen@ depth\dimen@ width\z@}}
\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@{\afteraliases@@\PATHlabels@}\fi\fi \next@}
\xylet@\afteraliases@@=\empty
\xydef@\savealias@#1{\xy@@{\enter@\cfromthec@
 \advance\X@c-\L@c \advance\L@c\R@c \L@c=.5\L@c \R@c=\L@c \advance\X@c\L@c 
 \advance\Y@c-\D@c \advance\D@c\U@c \D@c=.5\D@c \U@c=\D@c \advance\Y@c\D@c 
 \idfromc@{#1}\leave@}}
\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}%
 \edef\artail@@{\arvariant@@{}}%
 \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}}\change@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{%
 \DN@##1##{\DN@{##1}\ifx\next@\empty
 \DN@{\expandafter\nextii@\expandafter{\arvariant@@}}%
 \else \DN@{\nextii@{##1}}\fi \next@}%
 \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@}%
 \resetvariant@\artail@@
 \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\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{%
 \def\next{%
 \afterPATH{#9}%
 ~={#6\preconnect#5#3#2}%
 ~/{#7}%
 ~<{|<*h#5\dir#1}%
 ~>{|>*h#5\dir#4}%
 ~+{#8}%
 }%
 \next}}
\xylet@\ar@PATH=\next
\xydef@\arafterPOS@#1{%
 \arsavedPATHafterPOS@@{\let\PATHafterPOS=\arsavedPATHafterPOS@@
 \DN@{#1}\expandafter\next@\arafterPOS@@}}%
\xylet@\arsavedPATHafterPOS@@=\relax
\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@@{\crvi}\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.3 1996/12/19 03:31:56 krisrose Exp $
%%
%% Xy-pic ``Computer Modern tips'' extension.
%% Copyright (c) 1992-1996 Kristoffer H. Rose <krisrose@brics.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% Copyright (c) 1991-1996 Kristoffer H. Rose <krisrose@brics.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.3 $}%
 {Kristoffer H.~Rose}{krisrose@brics.dk}%
 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
 DK--8000 Aarhus~C}
\xyrequire{tips}\xycatcodes
\xydef@\UseComputerModernTips{\SelectTips{cm}{10}\UseTips}
\xydef@\NoComputerModernTips{\NoTips}
\xyendinput

xycurve.tex
%% xycurve.tex from $Id: xycurve.doc,v 3.7 1999/02/16 15:12:50 krisrose Exp $
%%
%% Xy-pic ``Curves and Splines'' extension.
%% Copyright (c) 1993-1997 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-1997 Kristoffer H. Rose <krisrose@ens-lyon.fr>
%%
%% 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.7 $}%
 {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@
 \def\pure@crv{\crv@saveStyles@}\crv@{#1}}
\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}%
\xydef@\pure@crv{\relax}
\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 \def\pure@crv{\relax}\crvs@{#1}}%
\xydef@\crvi#1#{\hbox \bgroup \def\pure@crv{\relax}\invisbreaks@ \crvs@{#1}}%
\xydef@\crvs@#1{\DN@{\initshape@ \@crv@{#1}}%
 \def\crv@defaultshape{-}%
 \ifx\bstartPLACE@\relax \else
 \ifx\bstartPLACE@\empty \Invisible@true \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@ \recovercv@end
 \ifx\bendPLACE@\relax \def\bendPLACE@{1}\fi
 \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@start{\cfromthep@}}
\xydef@\recovercv@end{\count@=\ptsnum@\relax\advance\count@\@ne
 \edef\tmp@{\the\count@}\csname cv@\tmp@\endcsname}%
\xydef@\crvSTYLE@@{}
\expandafter\xydef@\expandafter\crv@defaultshape\expandafter{\addDASH@{}}
\xydef@\crv@noobject{\Invisible@true}
\xydef@\@crv@#1#2{\DN@{#1#2}%
 \ifx\next@\empty \edef\next@{\crv@defaultshape}%
 \ifx\bstartPLACE@\empty \xdef\crvSTYLE@@{{\crv@defaultshape}}\fi
 \else 
 \ifx\bstartPLACE@\empty \gdef\crvSTYLE@@{#1{#2}}\fi
 \fi
 \ifx\next@\empty \crv@noobject \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\testAND@\iffalse \DN@##1{\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@
 \expandafter\noexpand\pure@crv
 \noexpand\ifInvisible@ \noexpand\crv@saveStyles@ \noexpand\else 
 \noexpand\crv@getStyles@\noexpand\styledboxz@ \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@\crvXY@pre@{}
\xydef@\crvXY@post@{}
\xydef@\crv@saveStyles@{\def\xy@style@{}%
 \expandafter\def\expandafter\crvXY@pre@\expandafter{\preXY@style@}%
 \expandafter\def\expandafter\crvXY@post@\expandafter{\postXY@style@}}
\xydef@\crv@getStyles@{\def\xy@style@{}%
 \gdef\preXY@style@{\crvXY@pre@}\gdef\postXY@style@{\crvXY@post@}}
\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@ \def\noexpand\pure@crv{\expandafter\noexpand\pure@crv}}%
 \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@}%
 \def\Cintercept@@{\crvintercept@}%
 \def\Cbreak@@{\crvbreak@}%
 \def\Clast@@{\crvlast@}%
}
\xydef@\straitconnect@{\crvconnect@@ 
 \let\crvreset@=\straitreset@
 \let\crvshavep@=\straitshavep@
 \let\crvshavec@=\straitshavec@
 \let\crvslidep@=\straitslidep@
 \let\crvslidec@=\straitslidec@
 \let\crvalong@=\straitalong@
 \let\crvintercept@=\straitintercept@
 \let\crvbreak@=\straitbreak@
 \let\crvlast@=\straitlast@
}
\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@\straitintercept@{\noCintercept@@}
\xydef@\straitbreak@{\straightCbreak@@}
\xydef@\straitlast@{\straightClast@@}
\xydef@\splineconnect@{%
 \let\crvreset@=\splinereset@
 \let\crvshavep@=\splineshavep@
 \let\crvshavec@=\splineshavec@
 \let\crvslidep@=\splineslidep@
 \let\crvslidec@=\splineslidec@
 \let\crvalong@=\splinealong@
 \let\crvintercept@=\splineintercept@
 \let\crvbreak@=\splinebreak@
 \let\crvlast@=\splinelast@
}
\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@{1}\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 \advance\dimen@\p@
%% \getcrvsegsnum@ \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
%% splinecorrect@c is probably wrong here!!
 \edef\tmp@{\endgroup \endgroup
 \noexpand\def\noexpand\xysplineval@{\the\splineval@}%
 \noexpand\def\noexpand\splinecorrect@c{\expandafter\removePT@\the\dimen@}%
\splinetrace@{slide = \the\splinelength@; correct@c=\noexpand\splinecorrect@c}%
 \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@@ 
 \dimen@=\xysplineval@\relax 
 \count@=\xycrvptsnum@\relax \ifnum\count@>\@ne \advance\count@\m@ne\fi
 \ifnum\count@>\@ne \dimen@nth\count@\dimen@
 \fi \edef\bthisPLACE@{\expandafter\removePT@\the\dimen@}%
\splinetrace@{bthisPLACE@=\bthisPLACE@}}%
\xydef@\splinealong@@#1#2#3{%
 \edef\tmp@{#1}\relax \dimen@ii\tmp@\p@ 
%% \getcrvsegsnum@
%% \dimen@=-\count@\p@ 
 \dimen@=-\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@
 \getcrvsegsnum@ \multiply \dimen@ by\count@\relax
\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}%
 \DNii@{\relax}\DN@{\begingroup}%
 \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@\resetbreaks@{%
 \let\bstartPLACE@=\relax \let\bthisPLACE@=\empty
 \let\bendPLACE@=\relax \let\bprevPLACE@=\relax}
\xydef@\invisbreaks@{\resetbreaks@ \let\bstartPLACE@=\empty}
\xydef@\crvresetbreaks@{\resetbreaks@ \let\bstartPLACE@=\relax }
\xydef@\initbreaks@{\xy@@{\ifx\bstartPLACE@\relax
 \def\bstartPLACE@{0}\def\bendPLACE@{1}\else
 \ifx\bstartPLACE@\empty\def\bstartPLACE@{0}\def\bendPLACE@{1}%
 \fi\fi}}
\xydef@\lastbreaks@{\ifx\bprevPLACE@\relax \def\bstartPLACE@{0}%
 \else \expandafter \bprevPLACE@ \fi 
 \let\bprevPLACE@\relax \let\bendPLACE@\relax}
\xylet@\bstartPLACE@\relax
\xylet@\bendPLACE@\relax
\xylet@\bprevPLACE@\relax
\xydef@\bthisPLACE@{1}
\xydef@\splinebreak@{%
\splinetrace@{***new break*** this:\bthisPLACE@ }%
 \ifx\bthisPLACE@\empty\def\bendPLACE@{1}%
 \else\edef\bendPLACE@{\bthisPLACE@}\let\bthisPLACE@\empty\fi
 \ifx\bprevPLACE@\relax\def\bstartPLACE@{0}\else\expandafter\bprevPLACE@\fi
 \edef\bprevPLACE@{\def\noexpand\bstartPLACE@{\bendPLACE@}\pfromthec@}%
\splinetrace@{splineBREAK: \bstartPLACE@ <> \bendPLACE@}%
 \edef\cv@brend{\cfromthec@}%
 \edef\cv@brstart{\cfromthep@}%
 \expandafter\connect\expandafter\crvs\crvSTYLE@@{}%
 \let\cv@brend=\relax
 \let\cv@brstart=\relax
\splinetrace@{**break done**}%
} 
\xydef@\splinelast@{\splinereset@ \lastbreaks@
\splinetrace@{splineLAST}%
 \edef\cv@brend{\cfromthec@}%
 \edef\cv@brstart{\cfromthep@}%
 \expandafter\connect\expandafter\crvs\crvSTYLE@@{}%
 \let\cv@brend=\relax
 \let\cv@brstart=\relax
\splinetrace@{**last done**}%
 \resetbreaks@}
\xydef@\splineNointercept@{\enter@{\pfromthep@}%
 \begingroup \splinereset@ \csname cv@0\endcsname \swap@ 
 \count@=\ptsnum@ \advance\count@\@ne \csname cv@\the\count@\endcsname 
 \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@\splineintercept@{\Hidden@true\Invisible@true\splineintercept@i}
\xydef@\splineintercept@i{\enter@{\pfromthep@}\begingroup 
 \R@p=\X@c \L@p=\X@p \d@X=\R@p \advance\d@X-\L@p
 \D@p=\Y@c \U@p=\Y@p \d@Y=\D@p \advance\d@Y-\U@p
 \dimen@nth\KK@\d@X \edef\sd@X{\expandafter\removePT@\the\d@X}%
 \dimen@nth\KK@\d@Y \edef\sd@Y{\expandafter\removePT@\the\d@Y}%
 \dimen@=\sd@Y\L@p \advance\dimen@-\sd@X\U@p 
 \edef\sideOffset@{\the\dimen@}\def\closestseg@{1}%
 \let\crvconnect@@=\relax \crvconnect@
 \let\spline@end=\splinef@end
 \def\spline@start{\bgroup \def\prevnext@{+-}%
 \def\splinerec@{\let\splinerec@=\splineIrec@ \splineinterceptTest@}%
 \def\splinedecast@{\let\splinedecast@=\splinedecast@@
 \def\splineadvance@{\splineIadvance@@}\splinedecast@@}%
 \def\splineadvance@{\intercepthull@}%
 \global\let\splinepoint=\splineIpt@@
 \global\let\splinegoal@=\splinef@pt
 \global\let\splinefinish@=\splinefinish@@}%
 \begingroup \splineIsegment@ 
 \splinesetparams@ \splined@@ \def\postfind@{}\splineIplace@
 \setupDirection@ii \leave@ }
\xydef@\splineIplace@{%
 \d@X=\dimen5 \d@Y=\dimen7 \dimen@=\splineval@
 \expandafter\count@\xycrvptsnum@\relax
 \ifnum\count@>\tw@ \advance\count@\m@ne
 \advance\dimen@\segmentnum@\p@ \advance\dimen@-\p@ 
 \dimen@nth\count@\dimen@
 \fi \edef\tmp@{\endgroup \endgroup
 \def\noexpand\PLACEf@{{\expandafter\removePT@\the\dimen@}}%
 \X@c=\dimen@i \Y@c=\dimen3
 \d@X=\the\d@X \d@Y=\the\d@Y }\tmp@
\splinetrace@{PLACE = \PLACEf@:(\the\X@c, \the\Y@c)}%
 \expandafter\edef\expandafter\bthisPLACE@\PLACEf@
 }
\xydef@\splineIrec@{\splineinterceptTest@ }
\xydef@\squineIpt@{\edef\tmp@{\endgroup
 \def\noexpand\prevnext@{\next}\begingroup}\tmp@ }
\xydef@\squineIadvance@{\edef\tmp@{\endgroup
 \def\noexpand\prevnext@{\next}\def\noexpand\howclose@{\howclose@}}%
 \tmp@ \splineadvance@@\begingroup}
\xydef@\cubicIpt@{\edef\tmp@{\endgroup
 \def\noexpand\prevnext@{\next}\begingroup}\tmp@ }
\xydef@\cubicIadvance@{\edef\tmp@{\egroup
 \def\noexpand\prevnext@{\next}\def\noexpand\howclose@{\howclose@}}%
 \tmp@ \splineadvance@@\bgroup}
\xydef@\splineIsegment@{\DN@{\splinesegment@\@ne}%
 \ifx\splinesegment@\squinesegment@\else
 \ifx\splinesegment@\cubicsegment@\else\DN@{\findIsegment@}%
 \fi\fi\next@}
\xydef@\findIsegment@{\expandafter\count@\xycrvptsnum@ \count@@\z@ 
 \loop@ \advance\count@@\@ne \bgroup 
 \expandafter\splinesegment@\expandafter{\the\count@@}%
 \xysidesofinterval@
 \findIsegment@i \repeat@ 
 \expandafter\dimen@\prevhowclose@ \relax
 \ifdim\dimen@=\z@ \edef\closestseg@{\the\count@@}\fi
 \expandafter\splinesegment@\expandafter{\closestseg@}}
\xydef@\findIsegment@i{%
 \expandafter\ifx\next \expandafter\findIsegment@ii
 \else\expandafter\findIsegment@x\fi \next@ }
\xydef@\findIsegment@ii{\expandafter\count@\xycrvptsnum@ \relax
 \advance\count@\m@ne \ifnum\count@>\segmentnum@\relax
 \expandafter\findIsegment@y\else\expandafter\findIsegment@x\fi}
\xydef@\findIsegment@x{%
 \edef\next@{\egroup\def\noexpand\next{\next}%
 \def\noexpand\prevhowclose@{\prevhowclose@}%
 \def\noexpand\closestseg@{\closestseg@}\noexpand\iffalse}}
\xydef@\findIsegment@y{%
 \edef\next@{\egroup\def\noexpand\next{\next}%
 \def\noexpand\prevhowclose@{\prevhowclose@}%
 \def\noexpand\closestseg@{\closestseg@}\noexpand\iftrue}}
\xydef@\xysidesofinterval@{\bgroup 
 \L@p=\sd@X\Y@p \advance\L@p-\sd@Y\X@p \advance\L@p\sideOffset@
 \U@p=\sd@X\Y@c \advance\U@p-\sd@Y\X@c \advance\U@p\sideOffset@
 \def\this@{}\ifdim\L@p>\almostz@ \ifdim\U@p>\almostz@ \def\next{++}\else
 \ifdim\U@p<-\almostz@ \def\next{+-}\else\def\next{+0}\def\this@{-}\fi\fi
 \else\ifdim\L@p<-\almostz@ \ifdim\U@p>\almostz@ \def\next{-+}\else
 \ifdim\U@p<-\almostz@ \def\next{--}\else\def\next{-0}\def\this@{+}\fi\fi
 \else \ifdim\U@p>\almostz@ \def\next{0+}\else
 \ifdim\U@p<-\almostz@ \def\next{0-}\else\def\next{00}\def\this@{+}\fi\fi
 \fi\fi
 \ifx\this@\empty
 \L@p=\ifdim\L@p<\z@-\fi\L@p \U@p=\ifdim\U@p<\z@-\fi\U@p 
 \ifdim\L@p<\U@p \edef\howclose@{\the\L@p}\def\this@{-}%
 \else \edef\howclose@{\the\U@p}\def\this@{+}\fi
 \else\def\howclose@{0.0pt}\fi 
\splinetrace@{\next:\this@:\howclose@;\the\splineval@:%
 (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c)}%
 \ifdim\howclose@<\prevhowclose@\relax 
 \edef\tmp@{\egroup\def\noexpand\this@{\this@}\def\noexpand\next{\next}%
 \def\noexpand\howclose@{\howclose@}\def\noexpand\prevhowclose@{\howclose@}%
 \def\noexpand\closestseg@{\segmentnum@}}%
\splinetrace@{closest yet: \howclose@, in segment \segmentnum@}%
 \else
 \edef\tmp@{\egroup\def\noexpand\this@{\this@}\def\noexpand\next{\next}%
 \def\noexpand\howclose@{\howclose@}}%
 \fi \tmp@ }
\xydef@\splineinterceptTest@{%
 \xysidesofinterval@ \DN@{\splineadvance@}%
 \DNii@{0.0pt}\ifx\howclose@\nextii@ \DN@{\splineclosest@}%
 \else\expandafter\ifx\next \expandafter\ifx\prevnext@
 \ifx\next\prevnext@\else\DN@{\X@c=\X@p \Y@c=\Y@p 
 \splinefinishf@}\fi\fi
 \else \DN@{\splinedecast@}\fi\fi 
 {\splinefar@false \splinenear@\X@p\X@c\Y@p\Y@c 
 \ifsplinefar@ \aftergroup\next@
 \else\aftergroup\splineclosest@
\splinetrace@{too close: (\the\X@p,\the\Y@p)::(\the\X@c,\the\Y@c)}%
 \fi}}
\xydef@\splineclosest@{%
 \expandafter\ifx\this@-\relax
 \X@c=\X@p \Y@c=\Y@p \global\advance\splineval@-\splinedepth@
 \fi \splinefinishf@ }%
\xydef@\squinetestcvxhull@{\begingroup
\splinetrace@{hull: closest in segment \closestseg@}%
 \expandafter\splinesegment@\ifx\undefined\closestseg@\@ne\else\closestseg@\fi
 \X@c=\L@c \Y@c=\U@c \xysidesofinterval@ 
 \expandafter\ifx\next \expandafter\splineoutsidehull@@
 \else \expandafter\splineinsidehull@\fi}
\xydef@\cubictestcvxhull@{\begingroup
 \expandafter\splinesegment@\ifx\undefined\closestseg@\@ne\else\closestseg@\fi
 \X@c=\L@c \Y@c=\U@c \xysidesofinterval@ 
 \expandafter\ifx\next \expandafter\cubictestcvxhull@i
 \else \expandafter\splineinsidehull@\fi}
\xydef@\cubictestcvxhull@i{%
 \X@c=\R@c \Y@c=\D@c \xysidesofinterval@ 
 \expandafter\ifx\next \expandafter\splineoutsidehull@@
 \else \expandafter\splineinsidehull@\fi}
\xydef@\xysidesofhull@{\bgroup 
 \L@p=\sd@X\Y@p \advance\L@p-\sd@Y\X@p \advance\L@p\sideOffset@
 \U@p=\sd@X\Y@c \advance\U@p-\sd@Y\X@c \advance\U@p\sideOffset@
 \L@p=\ifdim\L@p<\z@-\fi\L@p \U@p=\ifdim\U@p<\z@-\fi\U@p 
 \ifdim\L@p<\U@p \edef\howclose@{\the\L@p}\def\this@{-}%
 \else \edef\howclose@{\the\U@p}\def\this@{+}\fi
 \ifx\splinedecast@\squinedecast@ \D@c=\U@c \R@c=\L@c \fi
 \L@p=\sd@X\U@c \advance\L@p-\sd@Y\L@c \advance\L@p\sideOffset@
 \L@p=\ifdim\L@p<\z@-\fi\L@p 
 \expandafter\if\this@-%
 \ifdim\L@p<\prevhowclose@ \def\next{-+}\else \def\next{--}\fi
 \else
 \ifdim\L@p<\howclose@ \def\next{-+}\else 
 \U@p=\sd@X\D@c \advance\U@p-\sd@Y\R@c \advance\U@p\sideOffset@
 \U@p=\ifdim\U@p<\z@-\fi\U@p
 \ifdim\U@p<\howclose@ \def\next{+-}\else \def\next{++}\fi
 \fi\fi
 \edef\tmp@{\egroup\def\noexpand\this@{\this@}\def\noexpand\next{\next}%
 \def\noexpand\howclose@{\howclose@}}\tmp@ }
\def\PLACE@intercept@#1{%
 \xy@@{\enter@{\pfromthep@\basefromthebase@}\begingroup}%
 \xy@@ix@{#1}\xy@@{\plainxy@ \def\Creset@@{}%
 \expandafter\POS\the\toks9\relax
 \DNii@{\crvreset@}\ifx\nextii@\Creset@@ \edef\next@{\endgroup
 \def\noexpand\xyinterceptpts@{\the\crvpts@}%
 \X@c =\the\X@c \Y@c=\the\Y@c \X@p=\the\X@p \Y@p=\the\Y@p
 \noexpand\CCintercept@@ }%
 \else \edef\next@{\endgroup
 \X@c =\the\X@c \Y@c=\the\Y@c \X@p=\the\X@p \Y@p=\the\Y@p
 \noexpand\Cintercept@@ }%
 \fi \next@ \leave@}%
 \PLACE@@}
\xydef@\CCintercept@@{\splineSintercept@}
\xydef@\splineSintercept@{\enter@{\pfromthep@}\begingroup 
 \Creset@@ \edef\connect@pts{\cfromthec@ \pfromthep@}%
 \xyinterceptpts@ \splinereset@ \connect@pts \splineintercept@
 \edef\next@{\endgroup \cfromthec@ \DirectionfromtheDirection@ }%
 \next@ \let\xyinterceptpts@=\empty \leave@}
\xydef@\nointerceptwarning@{\let\nointerceptwarning@=\relax
 \xywarning@{perhaps no curve intersection, or many. }}
\xydef@\intercepthull@{\nointerceptwarning@ 
 \expandafter\def\expandafter\prevnext@\expandafter{\next}%
 \splinetestcvxhull@}
\xydef@\splinetestcvxhull@{\begingroup 
 \X@c=\L@c \Y@c=\U@c \splinetrace@{hull:}\xysidesofinterval@ 
 \expandafter\ifx\next \expandafter\splineoutsidehull@@
 \else \expandafter\splineinsidehull@\fi}
\xydef@\splineinsidehull@{\edef\tmp@{\endgroup 
 \def\noexpand\howcvxclose@{\howclose@}%
 \noexpand\interceptinsidehull@}\tmp@ }
\xydef@\interceptinsidehull@{\edef\prevhowclose@{\howclose@}%
 \splinedecast@@ }
{\xdef\next{\the\maxdimen}}
\xylet@\prevhowclose@=\next
\xydef@\splineoutsidehull@{\edef\tmp@{\endgroup
 \def\noexpand\howcvxclose@{\howclose@}%
 \noexpand\interceptoutsidehull@}\tmp@}
\xylet@\splineoutsidehull@@=\splineoutsidehull@
\xydef@\interceptoutsidehull@{\dimen@=\howcvxclose@ \relax
\splinetrace@{OUTSIDE HULL: \the\dimen@ : (\howclose@)(\prevhowclose@)}%
 \let\splinedecast@=\splinedecast@@
 \let\splinerec@\splineHnear@test
 \let\splineadvance@\splineIadvance@@
 \splinedecast@@ }
\xydef@\splineHnear@test{%
 \xysidesofhull@ \DN@{\splinedecast@}%
 \ifdim\howclose@<\prevhowclose@\edef\howclose@{\prevhowclose@}\fi
 \expandafter\if\this@-%
 \expandafter\ifx\next\DN@{\splineclosest@}\fi
 \else
 \expandafter\ifx\next\DN@{\splineadvance@}\fi
 \fi
 {\splinefar@false \splinenear@\X@p\X@c\Y@p\Y@c 
 \ifsplinefar@ \aftergroup\next@
 \else\aftergroup\splineclosest@
\splinetrace@{too close: (\the\X@p,\the\Y@p)::(\the\X@c,\the\Y@c)}%
 \fi}}
\xydef@\cubicoutsidehull@{\edef\tmp@{\endgroup
 \def\noexpand\howcvxclose@{\howclose@}}\tmp@
 \edef\prevhowcvxclose@{\howcvxclose@}\begingroup 
 \X@p=\R@c \Y@p=\D@c \splinetrace@{hullii:}\xysidesofinterval@ 
 \expandafter\ifx\next \expandafter\cubicoutsidehull@i
 \else \expandafter\cubicinsidehull@\fi} 
\xydef@\cubicinsidehull@{\edef\tmp@{\endgroup
 \def\noexpand\howclose@{\howclose@}}\tmp@
 \cubicoutsidehull@ii }
\xydef@\cubicoutsidehull@i{\edef\tmp@{\endgroup
 \def\noexpand\howcvxclose@{\howclose@}}\tmp@
 \dimen@=\prevhowcvxclose@\relax 
 \ifdim\dimen@<\howcvxclose@ \relax
 \edef\howcvxclose@{\the\dimen@}\expandafter\interceptoutsidehull@
 \else \expandafter\cubicoutsidehull@ii\fi }
\xydef@\cubicoutsidehull@ii{%
 \def\splineadvance@{\splineadvance@@}%
 \def\splinepoint\endgroup{\endgroup
 \global\let\splinepoint=\relax
 \def\splineadvance@{\intercepthull@}}%
 \splinedecast@@ }%
\xydef@\splineHadvance@{\futurelet\next@\splineHadvance@i}
\xydef@\splineHadvance@i{\ifx\next@\endgroup
 \expandafter\splineHadvance@x\else\expandafter\splineclosest@\fi}
\xydef@\splineHadvance@x{\edef\tmp@{\endgroup
 \def\noexpand\prevhowclose@{\prevhowclose@}%
 \def\noexpand\prevnext@{\next}\def\noexpand\howcvxclose@{\howclose@}}%
 \tmp@ \dimen@=\prevhowclose@ \relax
 \ifdim\dimen@<\howclose@ \relax \DN@{\splineclosest@\begingroup}%
 \else\ifdim\howcvxclose@=\dimen@\DN@{\splineclosest@\begingroup}%
 \else\DN@{\splineadvance@@\begingroup}\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@\startxycurve@=\startxycurve@@
\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@{ {}}%
 \edef\xycrvconn@{ \noexpand\dir{\addDASH@{}}}%
 \afterCURVE{\savecrvobjects@\xycvxhull@}\readxycurve@}
\xydef@\xyc@vxhull@@{%
 \afterCURVE{\savecrvobjects@\def\xycrvdrop@{ {}}%
 \edef\xycrvconn@{ \noexpand\dir{\addDASH@{}}}\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@\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@{}}\pfromc@
 \ifnum\crv@cnt@>\count@@@\relax \advance\count@@@\@ne\repeat@ 
 \cv@end }%
 \else
 \ifx\empty\xycrvconn@
 \edef\xycrvconn@{\noexpand!C\noexpand\dir{\addDASH@{}}}\fi
 \DN@{\relax}\fi \next@ 
 {{\expandafter\connect\xycrvconn@{}}}%
 \cv@end \cv@restore }
\xylet@\xycvxhull=\xycvxhull@
\xydef@\xycvxhulldrop@#1#{\drop@{#1}}
\xydef@\savespline@{%
\splinetrace@{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}%
\splinetrace@{getsplineedges@safe}%
 \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 
 \ifdim\dimen@>\p@ \xywarning@{edge out-of-range: \the\dimen@}%
 \count@=\dimen@ \divide\count@\p@
 \advance\dimen@-\count@\p@ \multiply\dimen@\m@ne
 \advance\dimen@ \count@\p@ \advance\dimen@\p@
\splinetrace@{\the\dimen@}%
 \else
 \multiply\dimen@\m@ne \advance\dimen@\p@
 \fi
 \global\dimen7=\dimen@ }
\xydef@\dimen@half{%
 \advance\dimen@ \ifdim\dimen@<\z@-\fi 1sp \divide\dimen@\tw@}
\xydef@\halve@dimen#1{\dimen@=#1\relax \dimen@half #1=\dimen@}
\xydef@\dimen@nth#1#2{\dimen@=#2\relax \dimen@ii=#1sp
 \advance\dimen@ \ifdim\dimen@<\z@-\fi.5\dimen@ii 
 \divide\dimen@ by#1\relax #2=\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@@}\expandafter\tmp@\expandafter{\Drop@@}%
 \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@<.1\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@@{%
\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}}
\xylet@\splinepoint=\splinepoint@
\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}%
\splinetrace@{bstartPLACE@:\bstartPLACE@; bendPLACE@:\bendPLACE@}%
 \DN@{\splinescan@}\ifx\bstartPLACE@\empty
 \ifx\bendPLACE@\relax\def\bendPLACE@{1}\fi
 \else\ifx\bstartPLACE@\relax
 \else\ifx\bstartPLACE@\undefined
 \else 
 \DN@{\splinescanbreak@}\ifx\bendPLACE@\relax\def\bendPLACE@{1}\fi
 \DNii@{0}\ifx\bstartPLACE@\nextii@
 \DNii@{1}\ifx\bendPLACE@\nextii@\DN@{}%
 \fi\fi
 \fi\fi\fi \next@ }%
\xydef@\splineStarttest@{{\X@p=\X@c \Y@p=\Y@c \cv@start \the\Edge@c\@ne 
 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}%
\xydef@\splineEndtest@{{\X@p=\X@c \Y@p=\Y@c \cv@end \the\Edge@c\@ne 
 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}%
\xydef@\splineBreakStarttest@{{\X@p=\X@c \Y@p=\Y@c \cv@brstart \the\Edge@c\@ne 
 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}%
\xydef@\splineBreakEndtest@{{\X@p=\X@c \Y@p=\Y@c \cv@brend \the\Edge@c\@ne 
 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}%
\xylet@\splineStarttest=\splineStarttest@
\xylet@\splineEndtest=\splineEndtest@
\xydef@\splineSlowStarttest{{\X@p=\X@c \Y@p=\Y@c \cv@start \the\Edge@c\@ne 
 \ifInside@\aftergroup\splineplot@maybe@@\else\aftergroup\splineplot@true\fi}}%
\xydef@\splineSlowEndtest{{\X@p=\X@c \Y@p=\Y@c \cv@end \the\Edge@c\@ne 
 \ifInside@\aftergroup\splineplot@maybe@@\else\aftergroup\splineplot@true\fi}}%
\xydef@\splineplot@maybe{\splineplot@false}%
\xylet@\splineplot@maybe@@=\splineplot@maybe
\xydef@\splinescan@{\bgroup%
 \expandafter\def\xysplineedges@{\z@;\z@,\z@;\z@,}%
 \bgroup \cv@start 
 \expandafter\DN@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
 \ifx\next@\nextii@ \gdef\splineedges@{\z@;\z@,}%
 \else\aftergroup\splinestartScan@\fi
 \egroup \relax
 \bgroup \cv@end 
 \expandafter\DN@\expandafter{\the\Edge@c}\DNii@{\zeroEdge}%
 \ifx\next@\nextii@ 
 \getcrvsegsnum@ \edef\segmentnum@{\the\count@}%
 \splineval@=\z@ \splineRecordEndValue@
 \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
 \xylowtolerance@ \splined@@ 
 \ifx\splineedges@\empty\expandafter\splineslowScan@\fi
 \ifx\splineedges@\relax\expandafter\splinenostart@\fi
 \egroup }%
\xydef@\splineslowScan@{%
 \let\splineStarttest=\splineSlowStarttest 
 \let\splinescanStarttest=\relax 
 \def\splinerec@{\let\splinerec@=\splineSrec@ \splinedecast@@}%
 \splined@@ }
\xydef@\splineslowEnd@{%
 \global\let\splineEndtest=\splineSlowEndtest 
 \let\splinescanEndtest=\relax 
 \def\splinerec@{\let\splinerec@=\splineErec@ \splinedecast@@}%
 \splined@@ }
\xydef@\splinenostart@{%
 \def\segmentnum@{1}\splinelength@=\z@ \splineval@=\z@
 \xynoedgespline@{start}\splineRecordValue@ }
\xydef@\splineendScan@{\bgroup
 \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@ 
 \global\let\splineEndtest=\splineEndtest@ 
 \def\splinerec@{\let\splinerec@=\splineErec@ \splinedecast@@}%
 \expandafter\def\expandafter\prevedges@\expandafter{\splineedges@}%
 \xylowtolerance@ \splined@@ 
 \ifx\splineedges@\prevedges@\expandafter\splineslowScan@\fi
 \egroup \egroup}
\xydef@\splinescanbreak@{%
\splinetrace@{SCANBREAK}%
 \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@{1}\splineRecordBreakValue@ \egroup}%
 \else
 \bgroup \cv@start 
 \expandafter\DN@\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@
%% \multiply\splineval@\m@ne \advance\splineval@\p@
%% \def\segmentnum@{1}
 \getcrvsegsnum@ \edef\segmentnum@{\the\count@}%
 \global\multiply\splineval@\count@ 
 \splineRecordEndBreakValue@ \egroup}%
 \else
 \bgroup \cv@end 
 \expandafter\DN@\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@\getcrvsegsnum@{%
 \count@=\ptsnum@\relax \ifnum\count@>\@ne\advance\count@\m@ne\fi}
\xydef@\splinezerostart{\DN@{\bgroup 
\splinetrace@{splinezerostart:}%
 \dimen@=\bstartPLACE@\p@ 
 \global\splineval@=\dimen@ 
 \splineRecordBreakValue@ \egroup }}
\xydef@\splinezeroend{\DN@{\bgroup 
\splinetrace@{splinezeroend:}%
 \dimen@=\bendPLACE@\p@
 \multiply\dimen@\m@ne \advance\dimen@\p@
 \def\segmentnum@{0}\global\splineval@=\dimen@ 
 \splineRecordEndBreakValue@ \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 wide 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@=\splineRecordEndValue@ \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@{BE (\the\X@p,\the\Y@p);(\the\X@c,\the\Y@c);;;
 \the\dimen@,\the\splinedepth@}%
 \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
 \ifdim\splinedepth@<\p@ \global\advance\splineval@\splinedepth@ \fi
 \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: bSTART=\bstartPLACE@, bEND=\bendPLACE@}%
 \DN@{#1}\def\DNii@{start}\ifx\next@\nextii@\splineRecordBreakValue@
 \else\splineRecordEndBreakValue@\fi\egroup}%
\xydef@\breakstartcontinue@{\bgroup \cv@start
 \expandafter\DN@\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\splineEndtest=\splineBreakStarttest@
 \global\let\splinetest@=\splineBreakStarttest@
 \gdef\splinerec@{\global\let\splinerec@=\splineSrec@ \splinedecast@@}%
 \global\let\splinepoint=\relax
 \global\let\spline@end=\checkfoundSbreak@ 
 \global\let\splinegoal@=\splineRecordSBreakValue@ 
 \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=\relax
 \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\splineRecordEndBreakValue@\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@ \splinedepth@=.5\p@}
\xydef@\breakendcontinue@{\bgroup
 \edef\tmp@{\X@p = \the\X@c \Y@p=\the\Y@c}\cv@end\tmp@
 \expandafter\DN@\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\splineEndtest=\splineBreakEndtest@
 \global\let\splinetest@=\splineBreakEndtest@
 \gdef\splinerec@{\global\let\splinerec@=\splineErec@\splinedecast@@}%
 \global\let\splinepoint=\relax
 \global\let\spline@end=\checkfoundEbreak@ 
 \global\let\splinegoal@=\splineRecordEBreakValue@ 
 \global\let\splinefinish@=\splinefinish@@ 
 \splinerec@ }
\xydef@\splineRecordEBreakValue@{%
\splinetrace@{\the\count@\space segments, \the\splineval@}%
 \splineRecordEndBreakValue@ }
\xydef@\splineRecordSBreakValue@{\getcrvsegsnum@
 \dimen@=\splineval@ 
 \advance\dimen@\segmentnum@\p@ \advance\dimen@-\p@
 \dimen@nth\count@\dimen@
 \global\splineval@=\dimen@ \def\segmentnum@{1}%
 \splineRecordBreakValue@ }
\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=\relax
 \global\let\splinegoal@=\splineRecordEndBreakValue@ 
 \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@=\splineRecordEndBreakValue@
 \global\splinelength@=\z@ 
 \let\splinerec@=\splineErec@ 
 \global\let\splineEndtest=\splineEndtest@ 
 \bgroup \splined@@ }
\xydef@\splinefindBEnd@{\bgroup\bgroup 
 \splinereverse@ \readsplineparams@ 
 \global\splineval@=\z@ }
\xydef@\splineRecordValue@{%
 \ifx\unknown\segmentnum@\relax
 \else
 \getcrvsegsnum@ 
 \dimen@=\splineval@ \advance\dimen@ \segmentnum@\p@
 \advance\dimen@-\p@ \dimen@nth\count@\dimen@
 \global\splineval@=\dimen@
 \fi
 \xdef\splineedges@{\splineedges@\the\splinelength@;\the\splineval@,}%
\splinetrace@{found edge: \splineedges@}}
\xydef@\splineRecordEndValue@{%
 \ifx\unknown\segmentnum@\relax
 \else
 \getcrvsegsnum@
 \dimen@=\splineval@ \advance\dimen@ \count@\p@
 \advance\dimen@-\segmentnum@\p@ \dimen@nth\count@\dimen@
 \global\splineval@=\dimen@
 \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@
 \count@=\segmentnum@\relax 
 \ifnum\count@>0 \advance\splineval@-\p@ \fi\fi
 \xdef\breakedges@{\breakedges@\the\splinelength@;\the\splineval@,}%
 \global\let\spline@end=\egroup
\splinetrace@{found break edge: \breakedges@}}
\xydef@\splineRecordEndBreakValue@{%
 \ifx\unknown\segmentnum@\relax 
 \else\count@=\segmentnum@\relax \ifnum\count@=\z@
 \else \getcrvsegsnum@ 
 \count@@=\count@ \advance\count@@-\segmentnum@\relax
 \dimen@=\splineval@ \advance\dimen@ \count@@\p@
 \dimen@nth\count@\dimen@
 \global\splineval@=\dimen@
 \fi\fi
 \ifdim\splineval@<\z@ \relax\splineval@=\z@ \fi
 \ifx\breakedges@\relax\relax\else\ifx\breakedges@\empty\else
 \ifdim\splineval@<\p@\relax \ifdim\splineval@>\z@ 
 \expandafter\testbreakedges@\breakedges@ @%
 \fi\fi\fi\fi
 \xdef\breakedges@{\breakedges@\the\splinelength@;\the\splineval@,}%
 \global\let\spline@end=\egroup
\splinetrace@{found break edge: \breakedges@}}
\xydef@\testbreakedges@#1;#2,#3@{\bgroup \dimen@=#2\relax
 \advance\dimen@\splineval@ \advance\dimen@-\p@
\splinetrace@{testbreak: #1;#2,#3@ \the\splineval@::\the\dimen@}%
 \DN@{\egroup}\ifdim\dimen@>\z@
 \edef\next@{\egroup\def\noexpand\breakedges@{#1;1pt,#3}}%
 \else\ifdim\zz@\dimen@ 
 \edef\next@{\egroup\def\noexpand\breakedges@{#1;1pt,#3}}%
 \fi \fi \next@ }
\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@ 
\splinetrace@{d=(\the\d@X,\the\d@Y): v=\the\splineval@: l=\the\splinelength@}%
}}
\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{%
\splinetrace@{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{%
\splinetrace@{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\splineval@=\z@ 
 \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 
 \global\splineval@=\z@ 
 \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
 \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{%
\splinetrace@{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@{%
\splinetrace@{splineset@:}%
 \ifx\bstartPLACE@\empty
 \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 \ifInvisible@\DN@{}\fi \next@ }
\xydef@\splinesolid@{\setbox\splinebox@=\zerodot \def\xycrvdrop@{ }%
 \def\xycrvconn@{}\splineset@@}
\xydef@\splinedoubled@{\splinedefaulttol@\def\xycrvdrop@{ }\def\splinedrop@{}%
 \def\xycrvconn@{!C\dir2{.}}\splineset@@}
\xydef@\splineribboned@{\splinedefaulttol@\def\xycrvdrop@{ }\def\splinedrop@{}%
 \def\xycrvconn@{!C\dir{:}}\splineset@@}
\xydef@\splinetrebled@{\splinedefaulttol@\def\xycrvdrop@{ }\def\splinedrop@{}%
 \def\xycrvconn@{!C\dir3{.}}\splineset@@}
\xydef@\splinedashed@{\splinetol@=1.5pc \def\xycrvdrop@{ }%
 \def\splinedrop@{}\edef\xycrvconn@{\noexpand!C\noexpand\dir{\addDASH@{}}}%
 \splineset@@}
\xydef@\splinedotted@{\setbox\splinebox@=\zerodot \def\xycrvdrop@{ }%
 \splinetol@=1.5\jot \def\xycrvconn@{}\splineset@@}
\xydef@\splinedbldotted@{\def\xycrvdrop@{ }\def\splinedrop@{}%
 \splinetol@=1.5\jot \def\xycrvconn@{!C\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: >\the\dimen5, <\the\dimen7}%
 \global\let\splineadvance@=\splineadvance@@
 \let\splinerec@=\splineTrec@
 \def\splineStarttest{\splinetest@}%
 \global\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@
%% \ifdim\bendPLACE@\p@=\z@ \emptyspline@ \else
 \ifdim\bendPLACE@\p@=\p@
 \fi
 \else
 \xdef\splinecontinue{\noexpand\setsplinetest@
 \splineval@>{\the\dimen7}{\noexpand\splinebreakcancel@}{}%
 \noexpand\splinesetting@ }%
 \fi\fi
 \ifdim\dimen7>\z@ \DN@{\splinesetting@\splinecontinue}%
 \ifdim\zz@{\dimen5}%
 \else 
 \edef\next@{\noexpand\setsplinetest@
 \splineval@<{\the\dimen5}{}%
 {\noexpand\expandafter\noexpand\splinecontinue}%
 \noexpand\splinesetting@ }%
 \fi
 \else\DN@{\dimen5=\p@}\fi
 \next@
 \ifdim\dimen5=\p@\DN@{}\else\DN@{\splined@@}\fi \next@ 
 }
\xydef@\emptyspline@{\xywarning@{empty curve subsegment}%
\splinetrace@{bstartPLACE@=\bstartPLACE@, bendPLACE@=\bendPLACE@, 
 empty segment}%
 \gdef\splinecontinue{\splinesetting@
 \global\let\splinetest@=\splineplot@false
 \global\dimen5=\z@ }}
\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@{\splinesetting@@}
\xydef@\splinesetting@@{%
\splinetrace@{splinesetting@@:}%
 \ifdim\splinedepth@=\z@ \splinedepth@=\p@ \fi
 \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@ \DN@{\splineglue@}\ifsplineplot@ 
 \DN@{\dosplineplotpt@}%
 \fi \next@ \global\dimen@i=\X@c \global\dimen3=\Y@c }}
\xydef@\splineglue@{\hglue-\dimen@i
\splinetrace@{N:(\the\X@c,\the\Y@c);;\the\dimen@i;\the\dimen3%
 ,\the\splinelength@,\the\splineval@,\the\splinedepth@}}
\xydef@\dosplineplotpt@{\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@}}
\xydef@\splinefinish@@{\postspline@ \splinegoal@ \splinecancel@ }
\xydef@\splinecancel@{%
 \global\let\splinerec@=\relax
 \global\let\splinepoint=\relax 
 \global\let\splinecontinue=\relax
 \global\let\splinedecast@=\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@
 \splinesetdir@ }
\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\splineIpt@@=\squineIpt@
 \let\splineIadvance@@=\squineIadvance@
 \let\splineinfo@=\squineinfo@
 \let\setsplinedir@=\setsquinedir@
 \let\splinetestcvxhull@=\squinetestcvxhull@
 \let\setsplineknotdir@=\setsquineknotdir@
 \let\splinereverse@=\squinereverse@
 \let\splineDadvance@@@=\squineDadvance@@@
 \let\splinesetparams@=\squinesetparams@
 \let\splineplot@maybe@@=\squineplot@maybe
}
\xydef@\squineconnect@{\splineconnect@ \crvconnect@@ 
 \let\splinesegment@=\squinesegment@ }%
\xydef@\squinesegment@#1{\xyquadmethods@ \def\segmentnum@{1}%
 \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@ \dimen@half
 \ifdim \dimen@>\X@max \X@max=\dimen@ \fi
 \dimen@=\X@c\advance\dimen@\A@ \dimen@half
 \ifdim \dimen@>\X@max \X@max=\dimen@ \fi
 \else \ifdim \A@<\X@min 
 \dimen@=\X@p\advance\dimen@\A@ \dimen@half
 \ifdim \dimen@<\X@min \X@min=\dimen@ \fi
 \dimen@=\X@c\advance\dimen@\A@ \dimen@half
 \ifdim \dimen@>\X@min \X@min=\dimen@ \fi
 \fi\fi
 \ifdim \B@>\Y@max 
 \dimen@=\Y@p\advance\dimen@\B@ \dimen@half
 \ifdim \dimen@>\Y@max \Y@max=\dimen@ \fi
 \dimen@=\Y@c\advance\dimen@\B@ \dimen@half
 \ifdim \dimen@>\Y@max \Y@max=\dimen@ \fi
 \else \ifdim \B@<\Y@min
 \dimen@=\Y@p\advance\dimen@\B@ \dimen@half
 \ifdim \dimen@<\Y@min \Y@min=\dimen@ \fi
 \dimen@=\Y@c\advance\dimen@\B@ \dimen@half
 \ifdim \dimen@>\Y@min \Y@min=\dimen@ \fi
 \fi\fi }
\xydef@\squinedecast@{\halve@dimen\splinedepth@
 \R@c=\L@c \advance\L@c\X@p \halve@dimen\L@c
 \advance\R@c\X@c \halve@dimen\R@c
 \A@=\L@c \advance\A@\R@c \halve@dimen\A@
 \D@c=\U@c \advance\U@c\Y@p \halve@dimen\U@c
 \advance\D@c\Y@c \halve@dimen\D@c
 \B@=\U@c \advance\B@\D@c \halve@dimen\B@
 \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@\squineplot@maybe{{\X@p=\L@c \Y@p=\U@c \cv@start \the\Edge@c\@ne 
 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}
\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@@{%
 \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\splineIpt@@=\cubicIpt@
 \let\splineIadvance@@=\cubicIadvance@
 \let\splineoutsidehull@@=\cubicoutsidehull@
 \let\splinetestcvxhull@=\cubictestcvxhull@
 \let\splineinfo@=\cubicinfo@
 \let\setsplinedir@=\setcubicdir@
 \let\setsplineknotdir@=\setcubicknotdir@
 \let\splinereverse@=\cubicreverse@ 
 \let\splineDadvance@@@=\cubicDadvance@@@
 \let\splinesetparams@=\cubicsetparams@
 \let\splineplot@maybe@@=\cubicplot@maybe
 }
\xydef@\cubicconnect@{\splineconnect@ \crvconnect@@
 \let\splinesegment@=\cubicsegment@ }%
\xydef@\cubicsegment@#1{\xycubicmethods@ \def\segmentnum@{1}%
 \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 \dimen@half 
 \ifdim\dimen@>\X@max \X@max=\dimen@ \fi \else
 \ifdim \A@<\X@min \dimen@=\A@ \advance\dimen@\X@p \dimen@half 
 \ifdim\dimen@<\X@min \X@min=\dimen@ \fi \fi\fi
 \ifdim \B@>\Y@max \dimen@=\B@ \advance\dimen@\Y@p \dimen@half 
 \ifdim\dimen@>\Y@max \Y@max=\dimen@ \fi \else
 \ifdim \B@<\Y@min \dimen@=\B@ \advance\dimen@\Y@p \dimen@half 
 \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi \fi\fi
 \ifdim \dimen3>\X@max \dimen@=\dimen3\advance\dimen@\X@c \dimen@half 
 \ifdim\dimen@>\X@max \X@max=\dimen@ \fi \else
 \ifdim \dimen3<\X@min \dimen@=\dimen3\advance\dimen@\X@c \dimen@half 
 \ifdim\dimen@<\X@min \X@min=\dimen@ \fi \fi\fi
 \ifdim \dimen5>\Y@max \dimen@=\dimen5\advance\dimen@\Y@c \dimen@half 
 \ifdim\dimen@>\Y@max \Y@max=\dimen@ \fi \else
 \ifdim \dimen5<\Y@min \dimen@=\dimen5\advance\dimen@\Y@c \dimen@half 
 \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi \fi\fi
 \dimen@=\A@ \advance\dimen@\dimen3 \dimen@half
 \ifdim\dimen@>\X@max \X@max=\dimen@
 \else \ifdim\dimen@<\X@min \X@min=\dimen@ \fi\fi
 \dimen@=\B@ \advance\dimen@\dimen5 \dimen@half
 \ifdim\dimen@>\Y@max \Y@max=\dimen@
 \else \ifdim\dimen@<\Y@min \Y@min=\dimen@ \fi\fi
}
\xydef@\cubicdecast@{\halve@dimen\splinedepth@
 \A@=\L@c \advance\A@\R@c \halve@dimen\A@
 \advance\R@c\X@c \halve@dimen\R@c
 \B@=\U@c \advance\B@\D@c \halve@dimen\B@
 \advance\D@c\Y@c \halve@dimen\D@c
 \advance\L@c\X@p \halve@dimen\L@c
 \advance\U@c\Y@p \halve@dimen\U@c
 \begingroup 
 \X@c=\R@c \advance\X@c\L@c \halve@dimen\X@c
 \advance\X@c\A@ \halve@dimen\X@c
 \Y@c=\D@c \advance\Y@c\U@c \halve@dimen\Y@c
 \advance\Y@c\B@ \halve@dimen\Y@c
 \R@c=\L@c \advance\R@c\A@ \halve@dimen\R@c
 \D@c=\U@c \advance\D@c\B@ \halve@dimen\D@c
 \bgroup \splinerec@ 
 \egroup \splinepoint \endgroup 
 \X@p=\L@c \advance\X@p\R@c \halve@dimen\X@p
 \advance\X@p\A@ \halve@dimen\X@p
 \L@c=\R@c \advance\L@c\A@ \halve@dimen\L@c
 \Y@p=\U@c \advance\Y@p\D@c \halve@dimen\Y@p
 \advance\Y@p\B@ \halve@dimen\Y@p
 \U@c=\D@c \advance\U@c\B@ \halve@dimen\U@c
 \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@\cubicplot@maybe{{\X@p=\L@c \Y@p=\U@c \cv@start \the\Edge@c\@ne 
 \ifInside@\aftergroup\cubicplot@maybeii\else\aftergroup\splineplot@true\fi}}
\xydef@\cubicplot@maybeii{{\X@p=\R@c \Y@p=\D@c \cv@start \the\Edge@c\@ne 
 \ifInside@\aftergroup\splineplot@false\else\aftergroup\splineplot@true\fi}}
\xydef@\cubiced@@{%
 \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\splineIpt@@=\cubicIpt@
 \let\splineIadvance@@=\cubicIadvance@
 \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@@{%
 \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@ \dimen@half
 \global\dimen3=\dimen@
 \dimen@=\Y@c \advance\dimen@\B@ \dimen@half
 \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@ \dimen@nth4\X@c
 \advance\X@c\dimen3\relax
 \advance\Y@c-\B@ \dimen@nth4\Y@c
 \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@ 
 \dimen@nth6\X@c
 \advance\Y@c 7\dimen5 \advance\Y@c-2\B@ 
 \dimen@nth6\Y@c
 \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 \halve@dimen\A@
 \B@=\Y@c \advance\B@\dimen5 \halve@dimen\B@
 \adjustmaxmin@ \leave@ \relax \cv@end
\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 \dimen@nth3\A@
 \advance\B@\Y@c \dimen@nth3\B@
 \advance\X@c\A@ \halve@dimen\X@c
 \advance\Y@c\B@ \halve@dimen\Y@c
 \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@
 \dimen@nth6\X@c
 \advance\Y@c 7\dimen5\advance\Y@c-2\B@
 \dimen@nth6\Y@c
 \enter@{\X@p=\the\X@c \Y@p=\the\Y@c \crv@cnt@=\segmentnum@\relax
 \noexpand\middlebspline@}%
 \else 
 \advance\X@c-\A@ \dimen@nth4\X@c
 \advance\X@c \dimen3\relax
 \advance\Y@c-\B@ \dimen@nth4\Y@c
 \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@\adjust@forsegments@{\getcrvsegsnum@ 
 \ifnum\count@>\@ne
\splinetrace@{adjust for \the\count@\space segments:
 \the\dimen5, \the\dimen7}%
 \multiply\dimen5 by \count@\relax \dimen@=\segmentnum@\p@
 \ifnum\dimen5>\dimen@ \relax\dimen5=\p@
 \else \advance\dimen5-\segmentnum@\p@ \advance\dimen5 by\p@ \fi
 \ifnum\dimen5<\z@ \relax\dimen5=\z@\relax\fi
 \multiply\dimen7 by \count@\relax
 \dimen@=\segmentnum@\p@
 \ifnum\dimen7<\dimen@ \advance\dimen@-\p@
 \ifnum\dimen7>\dimen@ \advance\dimen7-\dimen@
 \else \dimen7=\z@ \fi
 \else \dimen7=\p@ \fi
\splinetrace@{adjusted for \the\count@\space segments:
 \the\dimen5, \the\dimen7}%
 \fi}
\xydef@\adjustbsplineedges@{\bgroup
\splinetrace@{** adjusting edges **}%
 \readsplineparams@ \adjust@forsegments@
\splinetrace@{params:\xysplineparams@}%
\splinetrace@{segment \segmentnum@:<\the\dimen5,\the\dimen7>:\xysplineedges@}%
 \multiply\dimen7by\m@ne \advance\dimen7by\p@
 \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 \dimen@nth3\A@
 \advance\B@ by2\dimen5 \dimen@nth3\B@
 \dimen@=\dimen3 \advance\dimen@ by2\X@c
 \dimen@nth3\dimen@
 \global\dimen3=\dimen@
 \dimen@=\dimen5 \advance\dimen@ by2\Y@c
 \dimen@nth3\dimen@
 \global\dimen5=\dimen@
\splinetrace@{<: \the\dimen3, \the\dimen5}%
\splinetrace@{>: \the\A@, \the\B@}%
 \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@
 \dimen@nth6\X@p
 \advance\Y@p-2\dimen5\advance\Y@p by7\B@ 
 \dimen@nth6\Y@p
}
\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@ 
 \dimen@nth6\X@c
 \advance\Y@c by7\dimen5\advance\Y@c-2\B@ 
 \dimen@nth6\Y@c
\splinetrace@{>>: \the\X@c, \the\Y@c }%
}
\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@ 
 \dimen@nth4\X@p
 \advance\Y@p-\dimen5\advance\Y@p by4\B@ 
 \dimen@nth4\Y@p
\splinetrace@{<<: \the\X@p, \the\Y@p}%
}
\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@ 
 \dimen@nth4\X@c
 \advance\Y@c by4\dimen5\advance\Y@c-\B@ 
 \dimen@nth4\Y@c
}
\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@ \dimen@half
 \global\dimen3=\dimen@
\splinetrace@{2: \the\X@c, \the\Y@c}%
 \dimen@=\Y@c \advance\dimen@\B@ \dimen@half
 \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@ 
 \dimen@nth6\X@c
 \advance\Y@c by7\dimen5\advance\Y@c-2\B@ 
 \dimen@nth6\Y@c
 }
\xydef@\bsegment@z{%
 \expandafter\count@@\xycrvptsnum@ \advance\count@@\@ne 
 \xycontrolpt@{\the\count@@}\relax
\splinetrace@{\the\count@@: \the\X@c, \the\Y@c}%
 \advance\count@@\m@ne
 \bgroup
 \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 \halve@dimen\A@
 \B@=\Y@c \advance\B@\dimen5 \halve@dimen\B@
 \edef\tmp@{\egroup \A@=\the\A@ \B@=\the\B@ \count@@=\the\count@@}%
 \tmp@ }
\xydef@\bsegment@z@i{%
 \expandafter\count@@\xycrvptsnum@\relax\advance\count@@-\tw@ 
 \bgroup
 \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 \dimen@nth6\X@p
 \advance\Y@p by7\B@ \advance\Y@p-2\dimen5 \dimen@nth6\Y@p
 \edef\tmp@{\egroup \X@p=\the\X@p \Y@p=\the\Y@p}%
 \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 
 \expandafter\def\expandafter\segmentnum@\expandafter{\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@ 
 \dimen@nth4\X@c
 \advance\Y@c 4\dimen5\advance\Y@c-\B@ 
 \dimen@nth4\Y@c
 \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
 \dimen@nth4\X@p
 \advance\Y@p 4\B@ \advance\Y@p-\dimen5
 \dimen@nth4\Y@p
 \fi\fi
 \expandafter\def\expandafter\segmentnum@\expandafter{\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 
 \expandafter\def\expandafter\segmentnum@\expandafter{\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@@{\styledboxz@}\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}%
 \let\bstartPLACE@=\empty \connect@\crvs{#5}\relax\sinit@\sleave@
 \resetbreaks@}
\xydef@\dosolidcircle@#1{%
 \cubicCircleControls@@ 
 \doCircleQuadrant@@{#1}1 \relax\Clast@@
 \doCircleQuadrant@@{#1}2 \relax\Clast@@
 \doCircleQuadrant@@{#1}3 \relax\Clast@@
 \doCircleQuadrant@@{#1}4 \relax\Clast@@}%
\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@
 \dimen@nth\numobjects\dimen@
 \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@=\relax \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\crvresetbreaks@ \xy@spline@}
\xydef@\xy@spline@#1#{\if\sempty@ \DN@{\crvs@{}\resetbreaks@}%
 \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@
 \halve@dimen\X@c
 \halve@dimen\Y@c
 \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@
 \halve@dimen\X@c
 \halve@dimen\Y@c
 \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@
 \halve@dimen\X@c
 \halve@dimen\Y@c
 \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@ \resetbreaks@}%
 \def\Connect@@{\straight@\relax\splineConnect@ \resetbreaks@}%
 \OBJECT@x}
\xydef@\splineDrop@{\ifInvisible@\setboxz@h{}%
 \else\setboxz@h{\kern-\the\X@c\raise-\the\Y@c\hbox{\styledboxz@}}\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.7 1999/02/16 15:12:50 krisrose Exp $
%%
%% Xy-pic ``Frames and Brackets'' extension.
%% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.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-1997 Kristoffer H. Rose <krisrose@brics.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.7 $}%
 {Kristoffer H.~Rose}{krisrose@brics.dk}%
 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
 DK--8000 Aarhus~C}
\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@@#1{\zerocorner}
\xydef@\dashcorner@@#1{\zerocorner}
\xywithoption{curve}{%
 \let\dotcorner@@=\dotcorner@ \let\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@@}%
 \frame@fill@@\frmradius@@}}
\xydefcsname@{frm{**}}{%
 \expandafter\frmDrop@\expandafter{%
 \expandafter\def\expandafter\prevEdge@@\expandafter{\prevEdge@@}%
 \frame@emph@@\frmradius@@}}
\xydef@\frame@fill@#1{\filled@{#1}\empty}
\xydef@\frame@emph@#1{\framed@\frmradius@@}
\xylet@\frame@fill@@=\frame@fill@
\xylet@\frame@emph@@=\frame@emph@
\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@ \styledboxz@}
\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@{\saveframestyles@{\setbox\z@=\object##2\frm##1%
 \xypre@Style@@\Drop@@\xypost@Style@@\restoreframestyles@}}}%
 \expandafter\expandafter\expandafter\nextii@
 \expandafter\expandafter\expandafter{%
 \expandafter\whichframe@@\expandafter}\expandafter{\whichoptions@@}}
\xydef@\saveframestyles@{%
 \edef\afterframe@preStyle@{\preXY@style@}%
 \edef\afterframe@postStyle@{\postXY@style@}}
\xydef@\restoreframestyles@{%
 \xdef\preXY@style@{\afterframe@preStyle@}\def\afterframe@preStyle@{}%
 \xdef\postXY@style@{\afterframe@postStyle@}\def\afterframe@postStyle@{}}
\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@\UseCurveFrames@{%
 \let\circled@x@@=\xycircleframe@x@
 \let\ellipsed@x@@=\xyellipseframe@x@ }
\def\UseCurveFrames{\xywithoption{curve}{\UseCurveframes@}}%
\xydef@\UseFontFrames@{%
 \let\circled@x@@=\circled@x@
 \let\ellipsed@x@@=\ellipsed@x@ }
\xylet@\UseFontFrames=\UseFontFrames@
\xydef@\UnloadFrames@{%
 \let\framed@body@@=\framed@body@
 \let\circled@x@@=\circled@x@
 \let\ellipsed@x@@=\ellipsed@x@
 \let\frame@fill@@=\frame@fill@
 \let\frame@emph@@=\frame@emph@
 \let\filledRectangle@@=\bblacked@
 \let\filledCircle@@=\bblacked@
 \let\filledEllipse@@=\bblacked@
 \let\filledOval@@=\bblacked@
}
\xyaddunsupport{frame}\UnloadFrames@
\xyendinput

xyidioms.tex
%% xyidioms.tex from $Id: xyidioms.doc,v 3.4 1997/05/18 01:14:25 krisrose Exp $
%%
%% Format-dependent idioms for Xy-pic.
%% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.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-1997 Kristoffer H. Rose <krisrose@brics.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
\xylet@\xy@begindvi=\literal@
\ifx\undefined\AtBeginDvi\else
 \AtBeginDocument{\let\xy@begindvi=\AtBeginDvi}
 \AtBeginDvi{\global\let\xy@begindvi=\literal@}\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

xymatrix.tex
%% xymatrix.tex from $Id: xymatrix.doc,v 3.4 1997/05/18 01:14:25 krisrose Exp $
%%
%% Xy-pic ``Matrix'' feature.
%% Copyright (c) 1991-1997 Kristoffer H. Rose <krisrose@brics.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-1997 Kristoffer H. Rose <krisrose@brics.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.4 $}%
 {Kristoffer H.~Rose}{krisrose@brics.dk}%
 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
 DK--8000 Aarhus~C}
\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@
\xynew@{if}\ifnoisymatrices@ \noisymatrices@true
\xydef@\SilentMatrices{\noisymatrices@false}
\xydef@\NoisyMatrices{\noisymatrices@true}
\xydef@\xymatrixnocompile{\global\matrixsize@=\z@
 \ifnoisymatrices@\message{<xymatrix}\fi
 \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@ \mkHrow@ \mkHmax@
 \xdef\maxcol@{\the\Col}\xdef\maxcolrow@{\the\Row}\fi
 \ifnoisymatrices@\message{\maxcol@ x\maxrow@}\fi
 \xymatrix@measureit@@ \the\queue@ \global\queue@={}%
 \xymatrix@typeset{#1}\restore\xymatrix@insert
 \xy@@\leave@ \leave@
 \ifnoisymatrices@\message{\the\matrixsize@>}\fi \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@ \change@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@\mkHWmax@{}
\xydef@\mkHWdefaults@{\let\xymatrix@measureit@@=\xymatrix@measureit
 \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}%
 \let\mkHWmax@=\HWmax@max}
\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@\Hrow@HWmax{\expandafter\gdef\csname Hrow@\the\Row\endcsname{\HW@max}}
\xydef@\Wcol@HWmax{\expandafter\gdef\csname Wcol@\the\Col\endcsname{\HW@max}}
\xydef@\HWmax@max{%
 \ifdim\H@max>\W@max\global\let\HW@max=\H@max\else\global\let\HW@max=\W@max\fi}
\xydef@\HWmax@set#1{\gdef\HW@max{#1}%
 \global\let\H@max=\HW@max \global\let\W@max=\HW@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@}%
 \mkHWmax@}
\xylet@\xymatrix@measureit@@=\relax
\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
 \change@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 1\next \DN@1{\def\everyentry@{\vphantom(}%
 \let\objectmargin@=\p@ \xyFN@\xymatrix@setup}%
 \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 M\next \def\xymatrix@addop@@{\xymatrix@M}\DN@ M{\xymatrix@addop}%
 \else\ifx L\next \def\xymatrix@addop@@{\xymatrix@L}\DN@ L{\xymatrix@addop}%
 \else\ifx H\next \def\xymatrix@addop@@{\xymatrix@H}\DN@ H{\xymatrix@addop}%
 \else\ifx W\next \def\xymatrix@addop@@{\xymatrix@W}\DN@ W{\xymatrix@addop}%
 \else\ifx *\next \DN@*{\xyFN@\xymatrix@mods}%
 \else \DN@{\afterDIRECTIONorEMPTY
 {\xymatrix@rotation \xyFN@\xymatrix@setup}{%
 \xyerror@{<addop> or <direction> or one of RCMLHW*! expected}{}%
 \xyFN@\xymatrix@setup}}%
 \fi\fi\fi\fi\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@fix@}%
 \else\ifx C\next \let\mkWcol@=\Wcol@max \DN@ C{\xyFN@\xymatrix@fix@}%
 \else \let\mkHrow@=\Hrow@HWmax \let\mkWcol@=\Wcol@HWmax
 \let\next@=\xymatrix@fix@
 \fi\fi\fi \next@}
\xydef@\xymatrix@fix@{%
 \ifx \space@\next \expandafter\DN@\space{\xyFN@\xymatrix@fix@}%
 \else\ifx 0\next \def\mkHWmax@{\HWmax@set\z@}\DN@ 0{\xyFN@\xymatrix@setup}%
 \else\addEQ@\ifx\next \addEQ@\DN@{\afterassignment\xymatrix@fix@x\dimen@ii=}%
 \else \let\mkHWmax@=\HWmax@max \let\next@=\xymatrix@setup \fi\fi\fi \next@}
\xydef@\xymatrix@fix@x{%
 \edef\mkHWmax@{\noexpand\HWmax@set{\the\dimen@ii}}\xyFN@\xymatrix@setup}
\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@\xymatrix@M{\Addop@@\objectmargin@\dimen@ii}
\xydef@\xymatrix@L{\Addop@@\labelmargin@\dimen@ii}
\xydef@\xymatrix@H{\Addop@@\objectheight@\dimen@ii}
\xydef@\xymatrix@W{\Addop@@\objectwidth@\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.3 1996/12/19 03:31:56 krisrose Exp $
%%
%% Xy-pic ``Reset Category Codes'' utility.
%% Copyright (c) 1994-1996 Kristoffer H. Rose <krisrose@brics.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-1996 Kristoffer H. Rose <krisrose@brics.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

xytips.tex
%% xytips.tex from $Id: xytips.doc,v 3.3 1996/12/19 04:12:13 krisrose Exp $
%%
%% Xy-pic ``More Tips'' extension.
%% Copyright (c) 1992-1996 Kristoffer H. Rose <kris@diku.dk>
%%
%% This file is part of the Xy-pic package for graphs and diagrams in TeX.
%% Copyright (c) 1991-1996 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{tips}{More Tips extension}{\stripRCS$Revision: 3.3 $}%
 {Kristoffer H.~Rose}{kris@diku.dk}%
 {BRICS/Computer Science, University of Aarhus, Ny Munkegade, building 540,
 DK--8000 Aarhus~C}
\xylet@\tip@xy=\tip@
\xylet@\atip@xy=\atip@
\xylet@\btip@xy=\btip@
\xylet@\Tip@xy=\Tip@
\xylet@\Ttip@xy=\Ttip@
\xylet@\tipjot@xy=\tipjot@
\xyfont@\xy@@atfont=xycmat10
\xyfont@\xy@@btfont=xycmbt10
\xydef@\tipfamily@@{cm}
\xydef@\tipsize@@{10}
\xydef@\SelectTips#1#2{%
 \DN@{#1}\ifx\next@\empty\else \def\tipfamily@@{#1}\fi
 \DN@{#2}\ifx\next@\empty\else \def\tipsize@@{#2}\fi
 \csname tipfamily \tipfamily@@\endcsname \ignorespaces}
\xydefcsname@{tipfamily cm}{\loadtipfonts@
 \let\tip@=\tip@cm \let\atip@=\atip@cm \let\btip@=\btip@cm
 \let\Tip@=\Tip@xy \let\Ttip@=\Ttip@xy \def\tipjot@{.2em}}
\xydef@\loadtipfonts@{\edef\next##1##2{##1=xy\tipfamily@@##2\tipsize@@}%
 \next{\font\xy@@atfont}{at}
 \next{\font\xy@@btfont}{bt}
}
\xydef@\tip@cm{\activatetips@ \tip@x\tip@@}
\xydef@\atip@cm{\activatetips@ \tip@x\atip@@}
\xydef@\btip@cm{\activatetips@ \tip@x\btip@@}
\xydef@\activatetips@{\let\xyatipfont=\xy@@atfont \let\xybtipfont=\xy@@btfont}
\xydefcsname@{tipfamily eu}{\loadtipfonts@
 \let\tip@=\tip@cm \let\atip@=\atip@cm \let\btip@=\btip@cm
 \let\Tip@=\Tip@eu \let\Ttip@=\Ttip@eu \def\tipjot@{.15em}}
\xydef@\Tip@eu{\kern1.5pt \vrule height1.5pt depth1.5pt width\z@
 \Tip@@eu \kern1.5pt \egroup
 \U@c=1.5pt \D@c=1.5pt \L@c=1.5pt \R@c=1.5pt \Edge@c={\circleEdge}%
 \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
\xydef@\Tip@@eu{\count@=\DirectionChar
 \advance\count@-10 \ifnum\count@<\z@ \advance\count@128 \fi
 \xyatipfont\char\count@
 \advance\count@ 20 \ifnum127<\count@ \advance\count@-128 \fi
 \xybtipfont\char\count@}
\xydef@\Ttip@eu{\kern2.4pt \vrule height2.4pt depth2.4pt width\z@
 \Ttip@@eu \kern2.4pt \egroup
 \U@c=2.4pt \D@c=2.4pt \L@c=2.4pt \R@c=2.4pt \Edge@c={\circleEdge}%
 \Invisible@false \Hidden@false
 \def\Leftness@{.5}\def\Upness@{.5}%
 \def\Drop@@{\styledboxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
\xydef@\Ttip@@eu{%
 \setboxz@h\bgroup\reverseDirection@\line@ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@
 \kern-\L@c \boxz@ \kern\L@c \Tip@@eu}
\xydef@\UseTips{\csname tipfamily \tipfamily@@\endcsname}
\xydef@\NoTips{\let\tip@=\tip@xy \let\atip@=\atip@xy \let\btip@=\btip@xy
 \let\Tip@=\Tip@xy \let\Ttip@=\Ttip@xy \let\tipjot@=\tipjot@xy}
\xyendinput

cs0107022.extracted_bib
\begin{thebibliography}{}

\bibitem[\protect\citename{Bernstein, }1998]{Ber:CTSOS}
Bernstein, K. (1998).
\newblock A congruence theorem for structured operational semantics of
  higher-order languages.
\newblock {\em Pages  153--164 of:} {\em Proceedings of lics'98, 13th annual
  ieee symposium on logic in computer science}.
\newblock IEEE Computer Society Press.

\bibitem[\protect\citename{Berry \& Boudol, }1992]{BB:CAM}
Berry, G., \& Boudol, G. (1992).
\newblock The chemical abstract machine.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 96}(1), 217--248.

\bibitem[\protect\citename{Best {\em et~al.}\relax, }1997]{BdBP:POSOS}
Best, E., de~Boer, S., \& Palamidessi, C. (1997).
\newblock Partial order and sos semantics for linear constraint programs.
\newblock {\em Pages  256--273 of:} {\em Proceedings of coordination'97, 2nd
  international conference on coordination languages and models}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1282.
\newblock Springer Verlag.

\bibitem[\protect\citename{Bloom {\em et~al.}\relax, }1995]{BIM:BCBT}
Bloom, B., Istrail, S., \& Meyer, A.R. (1995).
\newblock Bisimulation can't be traced.
\newblock {\em Journal of the acm}, {\bf 42}(1), 232--268.

\bibitem[\protect\citename{Bossi {\em et~al.}\relax, }1994a]{BGLM:CSLP}
Bossi, A., Gabbrielli, M., Levi, G., \& Meo, M.C. (1994a).
\newblock A compositional semantics for logic programs.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 122}(1-2), 3--47.

\bibitem[\protect\citename{Bossi {\em et~al.}\relax, }1994b]{BGLM:SSA}
Bossi, A., Gabbrielli, M., Levi, G., \& Martelli, M. (1994b).
\newblock The s-semantics approach: Theory and applications.
\newblock {\em Journal of logic programming}, {\bf 19/20}, 149--197.

\bibitem[\protect\citename{Brogi {\em et~al.}\relax, }1992]{BLM:CMTS}
Brogi, A., Lamma, E., \& Mello, P. (1992).
\newblock Compositional model-theoretic semantics for logic programs.
\newblock {\em New generation computing}, {\bf 11}(1), 1--21.

\bibitem[\protect\citename{Bruni, }1999]{Bru:TL}
Bruni, R. (1999).
\newblock {\em Tile logic for synchronized rewriting of concurrent systems}.
\newblock Ph.D. thesis, Computer Science Department, University of Pisa.

\bibitem[\protect\citename{Bruni \& Montanari, }1999]{BM:CCDC}
Bruni, R., \& Montanari, U. (1999).
\newblock Cartesian closed double categories, their lambda-notation, and the
  pi-calculus.
\newblock {\em Pages  246--265 of:} {\em Proceedings of lics'99, 14th annual
  ieee symposium on logic in computer science}.
\newblock IEEE Computer Society Press.

\bibitem[\protect\citename{Bruni \& Montanari, }2000]{BM:ZSNCCI}
Bruni, R., \& Montanari, U. (2000).
\newblock Zero-safe nets: Comparing the collective and individual token
  approaches.
\newblock {\em Inform.\ and comput.}, {\bf 156}, 46--89.

\bibitem[\protect\citename{Bruni {\em et~al.}\relax, }1998]{BMM:PTTL}
Bruni, R., Meseguer, J., \& Montanari, U. (1998).
\newblock {\em Process and term tile logic}.
\newblock Tech. rept. SRI-CSL-98-06. SRI International.
\newblock Also Technical Report TR-98-09, Computer Science Department,
  University of Pisa.

\bibitem[\protect\citename{Bruni {\em et~al.}\relax, }1999]{BMM:ETS}
Bruni, R., Meseguer, J., \& Montanari, U. (1999).
\newblock Executable tile specifications for process calculi.
\newblock {\em Pages  60--76 of:} Finance, J.-P. (ed), {\em Proceedings of
  fase'99, fundamental approaches to software engineering}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1577.
\newblock Springer Verlag.

\bibitem[\protect\citename{Bruni {\em et~al.}\relax, }2000a]{BFMM:BC}
Bruni, R., de~Frutos-Escrig, D., Mart\'\i-Oliet, N., \& Montanari, U. (2000a).
\newblock Bisimilarity congruences for open terms and term graphs via tile
  logic.
\newblock {\em Pages  259--274 of:} Palamidessi, C. (ed), {\em Proceedings of
  concur 2000, 11th international conference on concurrency theory}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1877.
\newblock Springer Verlag.

\bibitem[\protect\citename{Bruni {\em et~al.}\relax, }2000b]{BMS:OES}
Bruni, R., Montanari, U., \& Sassone, V. (2000b).
\newblock Open ended systems, dynamic bisimulation and tile logic.
\newblock {\em Pages  440--456 of:} van Leeuwen, J., Watanabe, O., Hagiya, M.,
  Mosses, P.D., \& Ito, T. (eds), {\em Proceedings of ifip tcs 2000, ifip int.
  conf. on theoretical computer science}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1872.
\newblock Springer Verlag.

\bibitem[\protect\citename{Bruni {\em et~al.}\relax, }2001]{BMM:SMCDC}
Bruni, R., Meseguer, J., \& Montanari, U. (2001).
\newblock Symmetric monoidal and cartesian double categories as a semantic
  framework for tile logic.
\newblock {\em Math.\ struct.\ in comput.\ sci.}
\newblock To appear.

\bibitem[\protect\citename{Burstall \& Rydeheard, }1985]{BR:CUA}
Burstall, R.M., \& Rydeheard, D.E. (1985).
\newblock A categorical unification algorithm.
\newblock {\em Pages  493--505 of:} Abramsky, S., Pitt, D., Poigne, A., \&
  Rydeheard, D. (eds), {\em Proceedings of workshop on category theory and
  computer programming}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 240.
\newblock Springer Verlag.

\bibitem[\protect\citename{Cattani {\em et~al.}\relax, }2000]{CLM:CECAG}
Cattani, G.L., Leifer, J.J., \& Milner, R. (2000).
\newblock {\em Contexts and embeddings for a class of action graphs}.
\newblock Tech. rept. 496. Computer Laboratory, University of Cambridge.

\bibitem[\protect\citename{Corradini \& Montanari, }1992]{CM:ASSTS}
Corradini, A., \& Montanari, U. (1992).
\newblock An algebraic semantics for structured transition systems and its
  application to logic programs.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 103}, 51--106.

\bibitem[\protect\citename{De~Nicola \& Hennessy, }1984]{dNH:TEP}
De~Nicola, R., \& Hennessy, M. (1984).
\newblock Testing equivalences for processes.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 34}, 83--133.

\bibitem[\protect\citename{De~Simone, }1985]{DeS:HLSD}
De~Simone, R. (1985).
\newblock Higher level synchronizing devices in {MEIJE}--{SCCS}.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 37}, 245--267.

\bibitem[\protect\citename{Ehresmann, }1963a]{Ehr:CS}
Ehresmann, E. (1963a).
\newblock Cat\'egories structur\`ees: {I}--{II}.
\newblock {\em Annales \'ecole normal superieur}, {\bf 80}, 349--426.

\bibitem[\protect\citename{Ehresmann, }1963b]{Ehr:CS2}
Ehresmann, E. (1963b).
\newblock Cat\'egories structur\`ees: {III}.
\newblock {\em Cahiers de topologie ed g\'eom\'etrie diff\'erentielle}, {\bf
  5}.

\bibitem[\protect\citename{Emden \& Kowalski, }1976]{EK:SPLPL}
Emden, M.H.~van, \& Kowalski, R.A. (1976).
\newblock The semantics of predicate logic as a programming language.
\newblock {\em Journal of the acm}, {\bf 23}(4), 733--742.

\bibitem[\protect\citename{Falaschi {\em et~al.}\relax, }1984]{FLP:GHC}
Falaschi, M., Levi, G., \& Palamidessi, C. (1984).
\newblock A synchronization logic: Axiomatics and formal semantics of
  generalized horn clauses.
\newblock {\em Information and control}, {\bf 60}(1-3), 36--69.

\bibitem[\protect\citename{Falaschi {\em et~al.}\relax, }1989]{FLMP:DMOBLL}
Falaschi, M., Levi, G., Martelli, M., \& Palamidessi, C. (1989).
\newblock Declarative modeling of the operational behavior of logic languages.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 69}(3), 289--318.

\bibitem[\protect\citename{Ferrari \& Montanari, }2000]{FM:TFLMS}
Ferrari, G.L., \& Montanari, U. (2000).
\newblock Tile formats for located and mobile systems.
\newblock {\em Inform.\ and comput.}, {\bf 156}, 173--235.

\bibitem[\protect\citename{Fr\"uhwirth, }1995]{Fru:CHR}
Fr\"uhwirth, T.W. (1995).
\newblock Constraint handling rules.
\newblock {\em Pages  90--107 of:} Podelski, A. (ed), {\em Constraint
  {P}rogramming: {B}asics and {T}rends}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 910.
\newblock Springer Verlag.

\bibitem[\protect\citename{Gadducci \& Montanari, }1996]{GM:RRCCS}
Gadducci, F., \& Montanari, U. (1996).
\newblock Rewriting rules and {CCS}.
\newblock  {\em Proceedings of wrla'96, 1st workshop on rewriting logic and its
  applications}.
\newblock Elect.\ Notes in Th.\ Comput.\ Sci., vol. 4.
\newblock Elsevier Science.

\bibitem[\protect\citename{Gadducci \& Montanari, }2000]{GM:TM}
Gadducci, F., \& Montanari, U. (2000).
\newblock The tile model.
\newblock  Plotkin, G., Stirling, C., \& Tofte, M. (eds), {\em Proof, language
  and interaction: Essays in honour of {R}obin {M}ilner}.
\newblock MIT Press.
\newblock Also Technical Report TR-27/96, Dipartimento di Informatica,
  Universit\`a di Pisa, 1996.

\bibitem[\protect\citename{Gaifman \& Shapiro, }1989]{GS:FACS}
Gaifman, H., \& Shapiro, E. (1989).
\newblock Fully abstract compositional semantics for logic programs.
\newblock {\em Pages  134--142 of:} {\em Proceedings of popl'89}.
\newblock ACM.

\bibitem[\protect\citename{Goguen, }1989]{Gog:WIU}
Goguen, J. (1989).
\newblock What is unification? a categorical view of substitution, equation and
  solution.
\newblock {\em Pages  217--261 of:} Nivat, M., \& A{\"{\i}}t-Kaci, H. (eds),
  {\em Resolution of equations in algebraic structures}.
\newblock Academic Press.

\bibitem[\protect\citename{Groote \& Vaandrager, }1992]{GV:SOSBC}
Groote, J.F., \& Vaandrager, F. (1992).
\newblock Structured operational semantics and bisimulation as a congruence.
\newblock {\em Inform.\ and comput.}, {\bf 100}, 202--260.

\bibitem[\protect\citename{Jaffar \& Maher, }1994]{JM:CLPS}
Jaffar, J., \& Maher, M.J. (1994).
\newblock Constraint logic programming: A survey.
\newblock {\em Journal of logic programming}, {\bf 19/20}, 503--581.

\bibitem[\protect\citename{Larsen \& Xinxin, }1990]{LX:CTOSC}
Larsen, K.G., \& Xinxin, L. (1990).
\newblock Compositionality through an operational semantics of contexts.
\newblock {\em Pages  526--539 of:} Paterson, M.S. (ed), {\em Proceedings of
  icalp'90, 17th international colloquium on automata, languages and
  programming}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 443.
\newblock Springer Verlag.

\bibitem[\protect\citename{Lawvere, }1963]{Law:FSAT}
Lawvere, F.W. (1963).
\newblock Functorial semantics of algebraic theories.
\newblock {\em Proc. national academy of science}, {\bf 50}, 869--872.

\bibitem[\protect\citename{Leifer \& Milner, }2000]{LM:DBCRS}
Leifer, J.J., \& Milner, R. (2000).
\newblock Deriving bisimulation congruences for reactive systems.
\newblock {\em Pages  243--258 of:} Palamidessi, C. (ed), {\em Proceedings of
  concur 2000, 11th international conference on concurrency theory}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1877.
\newblock Springer Verlag.

\bibitem[\protect\citename{Lloyd, }1987]{Llo:FLP}
Lloyd, J.W. (1987).
\newblock {\em Foundations of logic programming}.
\newblock Springer Verlag.

\bibitem[\protect\citename{MacLane, }1971]{Mac:CWM}
MacLane, S. (1971).
\newblock {\em Categories for the working mathematician}.
\newblock Springer Verlag.

\bibitem[\protect\citename{Mancarella \& Pedreschi, }1987]{MP:ALP}
Mancarella, P., \& Pedreschi, D. (1987).
\newblock An algebra of logic programs.
\newblock {\em Pages  1006--1023 of:} R.A., Kowalski, \& A., Bowen~K. (eds),
  {\em Proceedings of iclp'88, 5th international conference on logic
  programming}.
\newblock MIT Press.

\bibitem[\protect\citename{Marriott \& Stuckey, }1998]{MS:PCI}
Marriott, K., \& Stuckey, P.J. (1998).
\newblock {\em Programming with constraints: an introduction}.
\newblock MIT Press.

\bibitem[\protect\citename{Meseguer, }1992]{Mes:CRL}
Meseguer, J. (1992).
\newblock Conditional rewriting logic as a unified model of concurrency.
\newblock {\em Theoret.\ comput.\ sci.}, {\bf 96}, 73--155.

\bibitem[\protect\citename{Meseguer \& Montanari, }1998]{MM:TLRL}
Meseguer, J., \& Montanari, U. (1998).
\newblock Mapping tile logic into rewriting logic.
\newblock {\em Pages  62--91 of:} Parisi-Presicce, F. (ed), {\em Proceedings of
  wadt'97, 12th workshop on recent trends in algebraic development techniques}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1376.
\newblock Springer Verlag.

\bibitem[\protect\citename{Miller, }1995]{Mil:LPILL}
Miller, D. (1995).
\newblock {\em lambda prolog: An introduction to the language and its logic}.
\newblock Unpublished. Available at
  \url{http://www.cse.psu.edu/~dale/lProlog/docs.html}.

\bibitem[\protect\citename{Miller \& Nadathur, }1998]{MN:HOLP}
Miller, D., \& Nadathur, G. (1998).
\newblock Higher-order logic programming.
\newblock {\em Pages  499--590 of:} Gabbay, D.M., Hogger, C.J., \& Robinson,
  J.A. (eds), {\em Handbook of logics for artificial intelligence and logic
  programming},  vol. 5.
\newblock Clarendon Press.

\bibitem[\protect\citename{Milner, }1980]{Mil:CCS}
Milner, R. (1980).
\newblock {\em A {C}alculus of {C}ommunicating {S}ystems}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 92.
\newblock Springer Verlag.

\bibitem[\protect\citename{Milner, }1992]{Mil:PPC}
Milner, R. (1992).
\newblock The polyadic pi-calculus (abstract).
\newblock {\em Page ~1 of:} Cleaveland, R. (ed), {\em Proceedings of concur
  '92, 3rd international conference on concurrency theory}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 630.
\newblock Springer Verlag.

\bibitem[\protect\citename{Milner, }1996]{Mil:CFI}
Milner, R. (1996).
\newblock Calculi for interaction.
\newblock {\em Acta inform.}, {\bf 33}(8), 707--737.

\bibitem[\protect\citename{Montanari \& Sassone, }1992]{MS:DCPB}
Montanari, U., \& Sassone, V. (1992).
\newblock Dynamic congruence vs. progressing bisimulation for {CCS}.
\newblock {\em Fundamenta informaticae}, {\bf 16}, 171--196.

\bibitem[\protect\citename{Montanari \& Talcott, }1998]{MT:APA}
Montanari, U., \& Talcott, C. (1998).
\newblock Can actors and $\pi$-agents live together?
\newblock  {\em Proceedings of hoots'98, 2nd workshop on higher order
  operational techniques in semantics}.
\newblock Elect.\ Notes in Th.\ Comput.\ Sci., vol. 10.
\newblock Elsevier Science.

\bibitem[\protect\citename{Park, }1981]{Par:CAIS}
Park, D. (1981).
\newblock Concurrency and automata on infinite sequences.
\newblock {\em Pages  167--183 of:} {\em Proceedings of fifth g-i conference}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 104.
\newblock Springer Verlag.

\bibitem[\protect\citename{Plotkin, }1981]{Plo:SAOS}
Plotkin, G. (1981).
\newblock {\em A structural approach to operational semantics}.
\newblock Tech. rept. DAIMI FN-19. Aarhus University, Computer Science
  Department.

\bibitem[\protect\citename{Rensink, }2000]{Ren:BOT}
Rensink, A. (2000).
\newblock Bisimilarity of open terms.
\newblock {\em Inform.\ and comput.}, {\bf 156}, 345--385.

\bibitem[\protect\citename{Saraswat, }1989]{Sar:CC}
Saraswat, V.A. (1989).
\newblock {\em Concurrent constraint logic programming}.
\newblock Ph.D. thesis, Carnegie-Mellon University.

\bibitem[\protect\citename{Sewell, }1998]{Sew:RRBC}
Sewell, P. (1998).
\newblock From rewrite rules to bisimulation congruences.
\newblock {\em Pages  269--284 of:} Sangiorgi, D., \& de~Simone, R. (eds), {\em
  Proceedings of concur'98}.
\newblock Lect.\ Notes in Comput.\ Sci., vol. 1466.
\newblock Springer Verlag.

\end{thebibliography}