Kasteleyn cokernels
Greg Kuperberg
We consider Kasteleyn and Kasteleyn-Percus matrices, which arise in enumerating matchings of planar graphs, up to matrix operations on their rows and columns. If such a matrix is defined over a principal ideal domain, this is equivalent to considering its Smith normal form or its cokernel. Many variations of the enumeration methods result in equivalent matrices. In particular, Gessel-Viennot matrices are equivalent to Kasteleyn-Percus matrices. We apply these ideas to plane partitions and related planar of tilings. We list a number of conjectures, supported by experiments in Maple, about the forms of matrices associated to enumerations of plane partitions and other lozenge tilings of planar regions and their symmetry classes. We focus on the case where the enumerations are round or $q$-round, and we conjecture that cokernels remain round or $q$-round for related ``impossible enumerations'' in which there are no tilings. Our conjectures provide a new view of the topic of enumerating symmetry classes of plane partitions and their generalizations. In particular we conjecture that a $q$-specialization of a Jacobi-Trudi matrix has a Smith normal form. If so it could be an interesting structure associated to the corresponding irreducible representation of $\SL(n,\C)$. Finally we find, with proof, the normal form of the matrix that appears in the enumeration of domino tilings of an Aztec diamond.
coker.tex
% Centered figure captions

\documentclass[twocolumn,amssymb,aps,nofootinbib]{revtex4}
\usepackage{times,mathptmx,amsthm,amsmath}
\usepackage{pstricks,pst-node}
\bibliographystyle{hamsplain}

\makeatletter
\renewcommand{\thesection}{\arabic{section}}
\renewcommand{\p@subsection}{}
\renewcommand{\thesubsection}{\arabic{section}.\arabic{subsection}}
\renewcommand{\p@subsubsection}{}
\renewcommand{\thesubsubsection}
    {\arabic{section}.\arabic{subsection}.\arabic{subsubsection}}
\makeatother

\newtheorem{theorem}{Theorem}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{problem}[theorem]{Problem}
\newtheorem{proposition}[theorem]{Proposition}
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{conjecture}[theorem]{Conjecture}
\newtheorem{example}[theorem]{Example}
\newtheorem{question}[theorem]{Question}
\theoremstyle{remark}
\newtheorem*{remark}{Remark}

\newcommand{\C}{\mathbb{C}}
\newcommand{\Z}{\mathbb{Z}}
\newcommand{\R}{\mathbb{R}}
\newcommand{\F}{\mathbb{F}}
\newcommand{\Sm}{\mathrm{Sm}}
\newcommand{\SL}{\mathrm{SL}}
\newcommand{\GL}{\mathrm{GL}}
\renewcommand{\tensor}{\otimes}
\DeclareMathOperator{\Pf}{Pf}
\DeclareMathOperator{\im}{im}
\DeclareMathOperator{\coker}{coker}
\newcommand{\braket}[1]{{\langle #1 \rangle}}

\newcommand{\vx}{\vec{x}}
\newcommand{\vq}{\vec{q}}
\newcommand{\tZ}{\tilde{Z}}
\newcommand{\tA}{\tilde{A}}

\newcommand{\eatline}{\vspace{-\baselineskip}}
\newcommand{\ie}{\textit{i.e.}}

\newcommand{\eq}[2]{\begin{equation}\label{#1}#2\end{equation}}

\renewcommand{\figurename}{Figure}
\newenvironment{fullfigure}[2]
    {\begin{figure}[htb]\begin{center}\def\ffa{#1}\def\ffb{#2}}
    {\vspace{\baselineskip}\caption{\ffb}\label{\ffa}\end{center}\end{figure}}

\renewcommand{\tablename}{Table}
\renewcommand{\thetable}{\arabic{table}}
\newenvironment{fulltable}[2]
    {\begin{table}[htb]\begin{center}\def\ffa{#1}\def\ffb{#2}}
    {\vspace{\baselineskip}\caption{\ffb.}\label{\ffa}\end{center}\end{table}}

\newcommand{\fig}[1]{Figure~\ref{#1}}
\newcommand{\thm}[1]{Theorem~\ref{#1}}
\renewcommand{\sec}[1]{Section~\ref{#1}}

\psset{linewidth=.5pt,dash=4pt 4pt,unit=.25in,arrowsize=2pt 3}
\SpecialCoor

\newcommand{\mto}{\lput{:U}{\pspicture(0,0)(0,0)
\psline[arrows=->](2.3pt,0)(2.4pt,0)\endpspicture}}

\begin{document}
\title{Kasteleyn cokernels}
\author{Greg Kuperberg}
\thanks{Supported by NSF grants DMS \#9704125 and DMS \#0072342,
and by a Sloan Foundation Research Fellowship}
\affiliation{UC Davis}
\email{greg@math.ucdavis.edu}
\begin{abstract}
We consider Kasteleyn and Kasteleyn-Percus matrices, which arise in
enumerating matchings of planar graphs, up to matrix operations on their rows
and columns.  If such a matrix is defined over a principal ideal domain, this
is equivalent to considering its Smith normal form or its cokernel.  Many
variations of the enumeration methods result in equivalent matrices.  In
particular, Gessel-Viennot matrices are equivalent to Kasteleyn-Percus
matrices.

We apply these ideas to plane partitions and related planar of tilings. We
list a number of conjectures, supported by experiments in Maple, about the
forms of matrices associated to enumerations of plane partitions and other
lozenge tilings of planar regions and their symmetry classes.  We focus on the
case where the enumerations are round or $q$-round, and we conjecture that
cokernels remain round or $q$-round for related ``impossible enumerations'' in
which there are no tilings. Our conjectures provide a new view of the topic of
enumerating symmetry classes of plane partitions and their generalizations. In
particular we conjecture that a $q$-specialization of a Jacobi-Trudi matrix
has a Smith normal form.  If so it could be an interesting structure
associated to the corresponding irreducible representation of $\SL(n,\C)$.
Finally we find, with proof, the normal form of the matrix that appears in the
enumeration of domino tilings of an Aztec diamond.

\end{abstract}
\maketitle

\section{Introduction}
\label{s:intro}

The permanent-determinant and Hafnian-Pfaffian methods of Kasteleyn and Percus
give determinant and Pfaffian expressions for the number of perfect matchings
of a planar graph \cite{Kasteleyn:crystal,Percus:dimer}.  Although the methods
originated in mathematical physics, they have enjoyed new attention in
enumerative combinatorics in the past ten years
\cite{Jockusch:perfect,Kuperberg:perdet,Kuperberg:fun,Kenyon:local,Yang:thesis},
in particular for enumerating lozenge and domino tilings of various regions in
the plane.   These successes suggest looking at further properties of the
matrices that the methods produce beyond just their determinants or Pfaffians.

In this article we investigate the cokernel, or equivalently the Smith normal
form, of a Kasteleyn or Kasteleyn-Percus matrix $M$ arising from a planar graph
$G$.  One theme of our general results in Sections~\ref{s:gv} and \ref{s:invar} is that
the cokernel is a canonical object that can be defined in several different
ways.  More generally for weighted enumerations we consider $M$ up to the
equivalence relation of general row and column operations. If $G$ has at least
one matching, then the set of matchings is equinumerous with $\coker M$.  (In
\sec{s:bijective}, we conjecture an interpretation of this fact in the spirit
of a bijection.) The cokernel of $M$ is also interesting even when the graph
$G$ has no matchings, a situation which we call an \emph{impossible
enumeration}.  Propp proposed another invariant of $M$ that generalizes to
impossible enumerations and that was studied by Saldanha
\cite{Propp:progress,Saldanha:singular}, namely the spectrum of $M^*M$.

The idea of computing cokernels as a refinement of enumeration also arose in
the context of Kirchoff's determinant formula for the number of spanning trees
of a connected graph.  In this context the cokernels are called \emph{tree
groups} and they were proposed independently by Biggs, Lorenzini, and Merris
\cite{Biggs:algebraic,Lorenzini:attached,Merris:unimodular}. Indeed, Kenyon,
Propp, and Wilson \cite{KPW:trees}, generalizing an idea due to Fisher
\cite{Fisher:planar}, found a bijection between spanning trees of a certain
type of planar graph $G$ and the perfect matchings of another planar graph
$G'$.  We conjecture that the tree group of $G$ is isomorphic to the
Kasteleyn-Percus cokernel of $G'$.

In \sec{s:pp} we study cokernels for the special case of enumeration of plane
partitions in a box, as well as related lozenge tilings. We previously asked
what is the cokernel of a Carlitz matrix, which is equivalent to the
Kasteleyn-Percus matrix for plane partitions in a box with no symmetry imposed
\cite{Propp:progress}. We give two conjectures that together imply an
answer.  Finally in \sec{s:domino} we derive, with proof, the cokernel for
the enumeration of domino tilings of an Aztec diamond.

\acknowledgments

The author would like to thank Torsten Ekedahl, Christian Krattenthaler, and
Martin Loebl for helpful discussions.  The author would especially like to thank
Jim Propp for his diligent interest in this work.

\section{Preliminaries}
\label{s:prelim}

\subsection{Graph conventions}
\label{s:graph}

In general by a \emph{planar} graph we mean a graph embedded in
the sphere $S^2$.  We mark one point of $S^2$ outside of the graph
as the infinite point; the face containing it is the infinite face.
Our graphs may have both self-loops and multiple edges,
although self-loops cannot participate in matchings.

\subsection{Matrix algebra}
\label{s:matrix}

Let $R$ be a commutative ring with unit.  We consider matrices $M$ over
$R$, not necessarily square, up to three kinds of equivalence:  general row
operations,
$$M \mapsto AM$$
with $A$ invertible; general column operations,
$$M \mapsto MA$$
with $A$ invertible; and stabilization,
$$M \mapsto \left(\begin{array}{c|c}1 & 0 \\ \hline 0 & M \end{array}\right)$$
and its inverse.  Any matrix $M'$ which is equivalent to $M$
under these operations is a \emph{stably equivalent form} of $M$.

A matrix $A$ over $R$ is \emph{alternating} if it is antisymmetric and has null
diagonal.  (Antisymmetric implies alternating unless 2 is a zero divisor in
$R$.)  We consider alternating matrices up to two kinds of equivalence:
general symmetric operations,
$$A \mapsto BAB^T$$
with $B$ invertible; and stabilization,
$$A \mapsto \left(\begin{array}{c|c}
\begin{matrix} 0 & 1 \\ -1 & 0 \end{matrix} & 0 \\ \hline 0 & M \end{array}\right)$$
and its inverse.  A matrix $A'$ which is equivalent to $A$ is also called a
\emph{stably equivalent form} of $A$.

As a special case of these notions, \emph{elementary row operation} on a matrix
$M$ consists of either multiplying some row $i$ by a unit in $R$, or adding some
multiple of some row $i$ to row $j \ne i$.  \emph{Elementary column operations}
are defined likewise. We define a \emph{pivot} on a matrix $M$ at the $(i,j)$
position as subtracting $M_{k,j}/M_{i,j}$ times row $i$ from row $k$ for all $k
\ne i$, then subtracting $M_{i,k}/M_{i,j}$ times column $j$ from column $k$ for
all $j \ne k$.  This operation is possible when $M_{i,j}$ divides every entry
in the same row and column.  In matrix notation, if $M_{1,1} = 1$, the pivot at
$(1,1)$ looks like this:
$$M = \left(\begin{array}{c|c}1 & Y^T \\ \hline X & M' \end{array}\right)
    \mapsto \left(\begin{array}{c|c}1 & 0 \\ \hline 0 & M'-XY^T \end{array}
    \right).$$
A \emph{deleted pivot} consists of a pivot at $(i,j)$ followed by
deleting row $i$ and column $j$ from the matrix.  The deleted
pivot at $(1,1)$ on our example $M$ looks like this:
$$M = \left(\begin{array}{c|c}1 & Y^T \\ \hline X & M' \end{array}\right)
    \mapsto M'-XY^T.$$

If $A$ is an alternating matrix, we define an \emph{elementary symmetric
operation} as an elementary row operation followed by the same operation
in transpose on columns.  We can similarly define a \emph{symmetric
pivot} and a \emph{symmetric deleted pivot}.  All of these operations
are special cases of general symmetric matrix operations, and therefore
preserve the alternating property.

If $R$ is a principal ideal domain (PID), then an $n \times k$ matrix $M$ is
equivalent to one called its \emph{Smith normal form} and denoted
$\Sm(M)$.  We define $\Sm(M)$ and prove its existence in \sec{s:smith}.
Note that if $M'$ is a stabilization of $M$, then $\Sm(M')$
is a stabilization of $\Sm(M)$.

If $R$ is arbitrary, then we can interpret $M$ as a homomorphism
from $R^k$ to $R^n$.  In this interpretation $M$ has a kernel $\ker M$,
an image $\im M$, and a cokernel
$$\coker M = R^n/\im M.$$
If $R$ is a PID, the cokernel carries the same information as the Smith normal
form.  Over a general ring $R$, only very special matrices admit a Smith normal
form.  Determining equivalence of those that do not is much more complicated
than for those that do.  In particular inequivalent matrices may have the same
cokernel.  However, over any ring $R$ the cokernel is invariant under stable
equivalence and it does determine the determinant $\det M$ up to a unit
factor.  A special motivation for considering cokernels appears when $R = \Z$
and $M$ is square.  In this case the absolute determinant (\ie, absolute value
of the determinant) is the number of elements in the cokernel,
$$|\det M| = |\coker M|,$$
when the cokernel is finite, while
$$\det M = 0$$
if the cokernel is infinite.

An alternating matrix $A$ over a PID is also equivalent to its antisymmetric
Smith normal form $\Sm_a(A)$, which we also discuss in \sec{s:smith}.  Again
$\coker A$ determines $\Sm_a(A)$.

\begin{remark} If $M$ is a matrix over the polynomial ring $\F[x]$ over an
algebraically closed field $\F$, which is a PID, then the factor exhaustion
method for computing $\det M$ \cite{Krattenthaler:advanced} actually computes
the Smith normal form (or cokernel) of $M$.  Thus the Smith normal form plays a
hidden role in a computational method which is widely used in enumerative
combinatorics.

The basic version of the factor exhaustion method computes the rank of the
reduction
$$M \tensor \F[x]/(x-r)$$
for all $r \in \F$.  These ranks determine $\det M$ up to a constant factor if
the Smith normal form of $M$ is square free.  It is tempting to conclude that
the factor exhaustion method ``fails'' if the Smith normal form is not square
free. But sometimes one can compute the cokernel of
$$M \tensor \F[x]/(x-r)^k,$$
for all $r$ and $k$.  This information determines $\coker M$, as well as $\det
M$ up to a constant factor, regardless of its structure.  Thus the factor
exhaustion method always succeeds in principle.
\end{remark}

\section{Counting matchings}
\label{s:counting}

Most of this section is a review of Reference~\citealp{Kuperberg:fun}.

\subsection{Kasteleyn and Percus}
\label{s:perdet}

Let $G$ be a connected finite graph.  If we orient the edges of $G$, then we
define the \emph{alternating adjacency matrix} $A$ of $G$ by letting $A_{i,j}$
be the number of edges from vertex $i$ to vertex $j$ minus the number of edges
from vertex $j$ to vertex $i$.  If $G$ is simple, then the Pfaffian $\Pf A$ has
one non-zero term for every perfect matching of $G$, but in general the terms
may not have the same sign.

\begin{theorem}[Kasteleyn] If $G$ is a simple, planar graph, then it admits an
orientation such that all terms in $\Pf A$ have the same sign, where  $A$ is
the alternating adjacency matrix of $G$ \cite{Kasteleyn:crystal}.
\label{th:kasteleyn}
\end{theorem}

In general an orientation of $G$ such that all terms in $\Pf A$ have the same
sign is called a \emph{Pfaffian orientation} of $G$.  If an orientation of $G$
is Pfaffian, then the absolute Pfaffian $|\Pf A|$ is the number of perfect
matchings of $G$.  Kasteleyn's rule for a Pfaffian orientation is that an odd
number of edges of each (finite) face of $G$ should point clockwise.  We call
such an orientation \emph{Kasteleyn flat} and the resulting matrix $A$ a
\emph{Kasteleyn matrix} for the graph $G$.  Likewise an orientation may be
Kasteleyn flat at a particular face if it satisfies Kasteleyn's rule at that
face. Every planar graph has a Kasteleyn-flat orientation, although it is only
flat at the infinite face of $G$ if $G$ has an even number of vertices.
Forming a Kasteleyn matrix to count matchings of a planar graph is also called
the \emph{Hafnian-Pfaffian method} \cite{Kuperberg:perdet}.

Percus \cite{Percus:dimer} found a simplification of the Hafnian-Pfaffian
method when $G$ is bipartite.  Suppose that $G$ is a bipartite graph with the
vertices colored black and white, and suppose that each edge has a sign $+$ or
$-$, interpreted as the weight $1$ or $-1$. Then we define the \emph{bipartite
adjacency matrix} $M$ of $G$ by letting $M_{i,j}$ be the total weight of all
edges from the black vertex $i$ to the white vertex $j$.  If $G$ is simple,
then the determinant $\det M$ has a non-zero term for each perfect matching of
$G$, but in general with both signs.

\begin{theorem}[Percus] If $G$ is a simple, planar, bipartite graph, then it
admits a sign decoration such that all terms in $\det M$ have the same sign,
where $M$ is the bipartite adjacency matrix of  $G$.
\label{th:percus}
\end{theorem}

In the rule given by Percus, the edges of each face of $G$ should
have an odd number of $-$ signs if and only if the face has $4k$ sides.
We call such a sign decoration of $G$ \emph{Kasteleyn flat} and the
corresponding matrix $M$ a \emph{Kasteleyn-Percus matrix}. Every planar graph
has a Kasteleyn-flat signing, although it is only flat at the infinite
face if $G$ has an even number of vertices.  Forming a Kasteleyn-Percus matrix
$M$ is also called the \emph{permanent-determinant method}. A Kasteleyn matrix
$A$ for a bipartite graph $G$ can be viewed as two copies of a Kasteleyn-Percus
matrix $M$:
$$A = \left(\begin{array}{c|c} 0 & M \\ \hline -M & 0 \end{array}\right).$$

\begin{fullfigure}{f:triple}{Tripling an edge in a graph.}
\pspicture(-1,-.5)(6.5,.5)
\psline(-.3,-.3)(0,0)(-.3,.3)\psline(-.5,0)(1.5,0)
\psline(1.3,.3)(1,0)(1.3,-.3)
\qdisk(0,0){.1}
\qdisk(1,0){.1}
\psline{->}(2,0)(3,0)
\psline(3.7,-.3)(4,0)(3.7,.3)
\psline(3.5,0)(6.5,0)
\psline(6.3,.3)(6,0)(6.3,-.3)
\qdisk(4,0){.1}
\qdisk(4.67,0){.1}
\qdisk(5.33,0){.1}
\qdisk(6,0){.1}
\endpspicture
\end{fullfigure}

If the graph $G$ is not simple, then we may make it simple by tripling edges,
as shown in \fig{f:triple}. The set of matchings of the new graph $G'$ is
naturally bijective with the set of matchings of $G$.  A more economical
approach is to define a  Kasteleyn matrix $A$ or a Kasteleyn-Percus matrix $M$
for $G$ directly. In this case $A_{ij}$ is the number of edges from vertex $i$
to vertex $j$ minus the number from $j$ to $i$, while $M_{ij}$ is the number of
positive edges minus the number of negative edges connecting $i$ and $j$.

A variant of the Hafnian-Pfaffian method applies to a projectively planar graph
$G$ which is \emph{locally but not globally bipartite}. This means that $G$ is
embedded in the projective plane and that all faces have an even number of
sides, but that $G$ is not bipartite.  An equivalent condition is that all
contractible cycles in $G$ have even length and all non-contractible cycles
have odd length.

\begin{theorem} If a projectively planar graph $G$ is locally but not globally
bipartite, then it admits a Pfaffian orientation. \cite{Kuperberg:fun}
\label{th:proj}
\end{theorem}

The orientation constructed in the proof of Theorem~\ref{th:proj} is one with
the property that each face has an odd number of edges pointing in each
direction.   We call such an orientation Kasteleyn flat; it exists if $G$ has
an even number of vertices.  (If $G$ has an odd number of vertices, then every
orientation is trivially Pfaffian.)  We call the corresponding alternating
adjacency matrix $A$ the Kasteleyn matrix of $G$ as usual.

The constructions of this section, in particular Theorems~\ref{th:kasteleyn}
and \ref{th:percus}, generalize to weighted enumerations of the matchings of
$G$, where each edge of $G$ is assigned a weight and the weight of a matching
is the product of the weights of its edges.  We separately assign signs or
orientations to $G$ using the Kasteleyn rule (in the general case) or the
Percus rule (in the bipartite case).  The weighted alternating adjacency matrix
$A$ is called a Kasteleyn matrix of $G$.  If $G$ is bipartite, the weighted
bipartite adjacency matrix $M$, with the weights multiplied by the signs, is a
Kasteleyn-Percus matrix of $G$.  Then $\Pf A$ or $\det M$ is the total weight
of all matchings in $G$.

\subsection{Polygamy and reflections}
\label{s:polygamy}

We can use the Hafnian-Pfaffian method to count certain generalized matchings
among the vertices of a planar graph $G$ using an idea originally due to Fisher
\cite{Fisher:planar}. We arbitrarily divide the vertices of $G$ into three
types:  Monogamous vertices, odd-polygamous vertices, and even-polygamous
vertices.  An \emph{odd-polygamous vertex} is one that can be connected to any
odd number of other vertices in a matching, while an \emph{even-polygamous
vertex} can be connected to any even number of other vertices (including
none).

\begin{fullfigure}{f:polyres}{Resolving polygamy into monogamy.}
\pspicture(-1,-.5)(5,.5)
\psline(-.3,-.3)(0,0)(-.3,.3)\psline(-.5,0)(.5,0)\psline(.3,.3)(0,0)(.3,-.3)
\pscircle[fillstyle=solid](0,0){.2}
\psline{->}(1,0)(2,0)
\psline(2.7,-.3)(3,0)(2.7,.3)\psline(2.5,0)(4.5,0)\psline(4.3,.3)(4,0)(4.3,-.3)
\pscircle[fillstyle=solid](3,0){.2}
\pscircle[fillstyle=solid](4,0){.2}
\endpspicture \\
\pspicture(-1,-.5)(5,.5)
\psline(-.3,-.3)(0,0)(-.3,.3)\psline(-.5,0)(.5,0)\psline(.3,.3)(0,0)(.3,-.3)
\pscircle[fillstyle=solid](0,0){.2}\qdisk(0,0){.07}
\psline{->}(1,0)(2,0)
\psline(2.7,-.3)(3,0)(2.7,.3)\psline(2.5,0)(4.5,0)\psline(4.3,.3)(4,0)(4.3,-.3)
\pscircle[fillstyle=solid](3,0){.2}
\pscircle[fillstyle=solid](4,0){.2}\qdisk(4,0){.07}
\endpspicture \\
\pspicture(-1,-.5)(5,.5)
\psline(-.5,0)(.5,0)
\pscircle[fillstyle=solid](0,0){.2}
\psline{->}(1,0)(2,0)
\psline(2.5,0)(4.5,0)
\qdisk(3,0){.1}\qdisk(4,0){.1}
\endpspicture \\
\pspicture(-1,-.5)(5,.5)
\psline(-.5,0)(0,0)(.25,.433)\psline(0,0)(.25,-.433)
\pscircle[fillstyle=solid](0,0){.2}
\psline{->}(1,0)(2,0)
\psline(2.5,0)(4,0)(4.25,.433)\psline(4,0)(4.25,-.433)
\qdisk(3,0){.1}\pscircle[fillstyle=solid](4,0){.2}\qdisk(4,0){.07}
\endpspicture \\
\pspicture(-1,-.5)(5,1.5)
\psline(0,.789)(0,.289)(.433,.039)
\psline(0,.289)(-.433,.039)
\pscircle[fillstyle=solid](0,.289){.2}\qdisk(0,.289){.07}
\psline{->}(1,.289)(2,.289)
\pspolygon(3,0)(4,0)(3.5,.866)(3,0)
\psline(3,0)(2.567,-.25)\psline(4,0)(4.433,-.25)\psline(3.5,.866)(3.5,1.366)
\qdisk(3,0){.1}\qdisk(4,0){.1}\qdisk(3.5,.866){.1}
\endpspicture
\end{fullfigure}

If $G$ is a graph with polygamous vertices, we can find a new graph $G'$ such
that the ordinary perfect matchings of $G'$ are bijective with the generalized
matchings of $G$.  The graph $G'$ defined from $G$ using a series of local
moves that are shown in \fig{f:polyres}.  (In this figure and later, an open
circle is an even-polygamous vertex and a dotted circle is an odd-polygamous
vertex.)  We also describe the moves in words.  First, if a polygamous vertex
of $G$ has valence greater than 3, we can split it into two polygamous vertices
of lower valence with the same total parity. This leaves polygamous vertices of
both parities of valence 1, 2, and 3.  If a polygamous vertex $v$ is even and
has valence 1, we can delete it.  If it is odd and has valence 1 or 2, it is
the same as an ordinary monogamous vertex.  If it is even and has valence 2, we
can replace it with two monogamous vertices.  If it is even and has valence 3,
we can split it into an odd-polygamous divalent vertex and an odd-polygamous
trivalent vertex.  Finally, if it odd and has valence 3, we can replace it with
a triangle.  Each of these moves comes with an obvious bijection between the
matchings before and after.  Thus these moves establish the following:

\begin{proposition}[Fisher]
Given a graph $G$ with odd- and even-polygamous vertices, the polygamous
vertices can be replaced by monogamous subgraphs so that the matchings of the
new graph $G'$ are bijective with those of $G$.  If $G$ is planar,
then $G'$ can be planar.
\end{proposition}

We call the resulting graph $G'$ a \emph{monogamous resolution} of $G$.
If $G$ is planar, then $G'$ admits Kasteleyn matrices, and we call
any such matrix a Kasteleyn matrix of $G$ as well.

\begin{fullfigure}{f:resmoves}{Moves on monogamous resolutions
of a polygamous graph.}
\pspicture(-1,-.5)(5.5,.5)
\psline(-.3,-.3)(.3,.3)
\psline(-.3,.3)(.3,-.3)
\psline(-.5,0)(.5,0)
\qdisk(0,0){.1}
\psline{->}(1,0)(2,0)
\psline(2.7,-.3)(3,0)(2.7,.3)
\psline(2.5,0)(5.5,0)
\psline(5.3,.3)(5,0)(5.3,-.3)
\qdisk(3,0){.1}
\qdisk(4,0){.1}
\qdisk(5,0){.1}
\endpspicture \\
\pspicture(-1,-2)(6.5,2)
\psline(-.5,0)(-1.366,.5)(-1.366,-.5)(-.5,0)
    (.5,0)(1.366,.5)(1.366,-.5)(.5,0)
\qdisk(-.5,0){.1}\qdisk(.5,0){.1}
\psline(-1.366,.5)(-1.616,.933)\psline(1.366,.5)(1.616,.933)
\psline(-1.366,-.5)(-1.616,-.933)\psline(1.366,-.5)(1.616,-.933)
\qdisk(-1.366,.5){.1}\qdisk(1.366,.5){.1}
\qdisk(-1.366,-.5){.1}\qdisk(1.366,-.5){.1}
\psline{->}(2.5,0)(3.5,0)
\psline(5,-.5)(5.5,-1.366)(4.5,-1.366)(5,-.5)
    (5,.5)(5.5,1.366)(4.5,1.366)(5,.5)
\qdisk(5,-.5){.1}\qdisk(5,.5){.1}
\psline(5.5,-1.366)(5.933,-1.616)\psline(5.5,1.366)(5.933,1.616)
\psline(4.5,-1.366)(4.067,-1.616)\psline(4.5,1.366)(4.067,1.616)
\qdisk(5.5,-1.366){.1}\qdisk(5.5,1.366){.1}
\qdisk(4.5,-1.366){.1}\qdisk(4.5,1.366){.1}
\endpspicture \\
\pspicture(-2,-.5)(5.5,1.8)
\psline(-2,0)(1,0)\psline(.5,0)(0,.866)(-.5,0)
\psline(0,.866)(0,1.366)
\qdisk(-.5,0){.1}\qdisk(.5,0){.1}
\qdisk(0,.866){.1}\qdisk(-1.5,0){.1}
\psline{->}(1.5,.289)(2.5,.289)
\psline(6,0)(3,0)\psline(3.5,0)(4,.866)(4.5,0)
\psline(4,.866)(4,1.366)
\qdisk(4.5,0){.1}\qdisk(3.5,0){.1}
\qdisk(4,.866){.1}\qdisk(5.5,0){.1}
\endpspicture
\end{fullfigure}

The monogamous resolution of a polygamous graph is far from unique.   But we
can consider moves that connect different monogamous resolutions of a
polygamous graph.   The moves are as shown in \fig{f:resmoves}: Doubly
splitting a vertex, rotating a pair of triangles, and switching a triangle with
an edge.  Each of these moves comes with a bijection between the matchings of
the two graphs that it connects.

\begin{proposition} Any two monogamous resolutions of a graph $G$
are connected by the moves of vertex splitting and its inverse,
switching triangles, and switching a triangle with an edge.
The moves also connect any two planar resolutions of a planar graph $G$
through intermediate planar resolutions.
\label{p:resmoves}
\end{proposition}

The proof of Proposition~\ref{p:resmoves} is routine.

\begin{fullfigure}{f:selfconn}{Removing a self-connected triangle.}
\pspicture(-.5,-1)(4.5,1)
\psline(-.5,0)(0,0)(.866,-.5)(.866,.5)(0,0)
\qdisk(0,0){.1}
\qdisk(.866,-.5){.1}
\qdisk(.866,.5){.1}
\psarc(.866,0){.5}{-90}{90}
\psline{->}(2,0)(3,0)
\psline(3.5,0)(4.2,0)
\qdisk(4.2,0){.1}
\endpspicture\eatline
\end{fullfigure}

Another interesting move is removing a self-connected triangle,
as shown in \fig{f:selfconn}.
This move induces a 2-to-1 map on the set of matchings before and after.

Polygamous matchings have two common applications.  If a graph $G$ is entirely
polygamous, then we can denote the presence or absence of each edge by an
element of $\Z/2$.  Each vertex then imposes a linear constraint on the
variables, so the number of matchings is therefore either 0 or $2^n$ for some
$n$.  The corresponding weighted enumerations are related to the Ising model
\cite{Kuperberg:fun,Waerden:reichweite,Fisher:planar}.  Another way to see that
the number of matchings is a power of two is to use the moves in
Figures~\ref{f:resmoves} and \ref{f:selfconn} to reduce a monogamous
resolution of $G$ to a tree, which has at most one matching.

\begin{fullfigure}{f:polytied}{Using polygamy to count reflection-invariant
    matchings.}
\pspicture(-3,-4)(9,4)
\pspolygon(-2.5,.5)(-2.5,-.5)(2.5,-.5)(2.5,.5)
\pspolygon(-1.5,1.5)(-1.5,-1.5)(1.5,-1.5)(1.5,1.5)
\pspolygon(.5,-2.5)(-.5,-2.5)(-.5,2.5)(.5,2.5)
\multips( -.5, 2.5)(1,0){2}{\qdisk(0,0){.1}}
\multips(-1.5, 1.5)(1,0){4}{\qdisk(0,0){.1}}
\multips(-2.5,  .5)(1,0){6}{\qdisk(0,0){.1}}
\multips(-2.5, -.5)(1,0){6}{\qdisk(0,0){.1}}
\multips(-1.5,-1.5)(1,0){4}{\qdisk(0,0){.1}}
\multips( -.5,-2.5)(1,0){2}{\qdisk(0,0){.1}}
\psline[linestyle=dashed](0,-4)(0,4)
\psline{->}(3.5,0)(4.5,0)
\pspolygon(5.5,0)(6.5,2.5)(6.5,-2.5)
\pspolygon(5.5,0)(6.5,1.5)(7.5,1.5)(7.5,-1.5)(6.5,-1.5)
\pspolygon(5.5,0)(6.5,.5)(8.5,.5)(8.5,-.5)(6.5,-.5)
\multips(6.5,2.5)(0,-1){6}{\qdisk(0,0){.1}}
\multips(7.5,1.5)(0,-1){4}{\qdisk(0,0){.1}}
\multips(8.5, .5)(0,-1){2}{\qdisk(0,0){.1}}
\pscircle[fillstyle=solid](5.5,0){.2}
\endpspicture
\end{fullfigure}

Another application is counting matchings invariant under reflections
\cite{Kuperberg:perdet,Kuperberg:fun}.  Suppose that a planar graph $G$ has a
reflection symmetry $\sigma$, and suppose that the line of reflection bisects
some of the edges of $G$.  Then the $\sigma$-invariant matchings of $G$ are
bijective with a modified quotient graph $G//\sigma$ in which the bisected
edges are tied to a polygamous vertex, as in \fig{f:polytied}.
The parity of the polygamous vertex should be set so that the total parity
(odd-polygamous plus monogamous vertices) is even. The same construction works
if we divide $G$ by any group acting on the sphere that includes reflections,
since all of the reflective boundary can be reached by a single polygamous
vertex.

\subsection{Gessel-Viennot}
\label{s:gv}

The Gessel-Viennot method \cite{GV:binomial,GV:partitions} yields another
determinant expression for a certain sum over the sets of disjoint paths in an
acyclic, directed graph $G$.  (Theorem~\ref{th:gv} below, which is the basic
result of the method, was independently found by Lindstr\"om
\cite{Lindstrom:vector}.  Gessel and Viennot were the first to use it for
unweighted enumeration.) The graph $G$ need not be planar.  We label some of
the vertices of $G$ as left endpoints and some as right endpoints, and we
separately order the left endpoints and the right endpoints. Let $P$ be the set
of collections of vertex-disjoint paths in $G$ connecting the left endpoints to
the right endpoints. If $P$ is non-empty then there are the same number of left
and right endpoints on left and right; if there are $n$ of each we call the
elements of $P$ \emph{disjoint $n$-paths}. The Gessel-Viennot matrix $V$ is
defined by setting $V_{i,j}$ to the number of paths in $G$ from left endpoint
$i$ to right endpoint $j$.

\begin{theorem}[Lindstr\"om, Gessel-Viennot]
Let $G$ be a directed, acyclic, weighted graph with $n$ ordered left endpoints
and $n$ ordered right endpoints.  Let $P$ be the set of disjoint $n$-paths in
$G$ connecting left to right.  If $V$ is the Gessel-Viennot matrix of $G$, then
\eq{e:gv}{\det V = \sum_{\ell \in P} w(\ell) (-1)^\ell.}
Here $(-1)^\ell$ is the sign of the bijection from the left to the right
endpoints induced by the paths in the collection $\ell$, and $w(\ell)$ is the
product of the weights of the edges of $G$ that appear in $\ell$.
\label{th:gv}
\end{theorem}
\begin{proof} We outline a non-traditional proof that will be useful later.  We
first suppose that the left endpoints are the sources in $G$ (the vertices with
in-degree 0) and the right endpoints are the sinks (the vertices with
out-degree 0). We argue by induction on the number of \emph{transit
vertices}, meaning vertices that are neither sources nor sinks.

\begin{fullfigure}{f:gvsplit}{Splitting a transit vertex.}
\pspicture(-1,-1)(6,1)
\pcline(-.5,.866)(0,0)\mto\pcline(-1,0)(0,0)\mto\pcline(-.5,-.866)(0,0)\mto
\pcline(0,0)(1,0)\mto\pcline(0,0)(.5,.866)\mto\pcline(0,0)(.5,-.866)\mto
\qdisk(0,0){.1}
\rput[t](0,-.5){$p$}
\psline{->}(1.5,0)(2.5,0)
\pcline(3.5,.866)(4,0)\mto\pcline(3,0)(4,0)\mto\pcline(3.5,-.866)(4,0)\mto
\pcline(5,0)(6,0)\mto\pcline(5,0)(5.5,.866)\mto\pcline(5,0)(5.5,-.866)\mto
\pcline(5,0)(4,0)\mto\qdisk(4,0){.1}\qdisk(5,0){.1}
\rput[tl](4,-.3){$q$}
\rput[tr](5,-.3){$r$}
\endpspicture\eatline
\end{fullfigure}

If $G$ has no transit vertices, every path in $G$ has length one. Consequently
the $n$-paths in $G$ are perfect matchings, and equation~\eqref{e:gv}
is equivalent to the definition of the determinant.  Suppose then that
$p$ is a transit vertex in $G$.  We form a new graph $G'$ by splitting $p$
into two vertices $q$ and $r$, with $q$ a sink and $r$ a source,
as shown in \fig{f:gvsplit}.
We number $q$ and $r$ as the $n+1$st (last) source and sink in $G'$. We give
the new edge between $q$ and $r$ a weight of $-1$. There is a natural bijection
between disjoint $n$-paths $\ell$ in $G$ and disjoint $n+1$-paths $\ell'$ in
$G'$:  Every path in $\ell$ which avoids $p$ is included in $\ell'$.  If some
path in $\ell$ meets $p$, we break it into two paths ending at $q$ and starting
again at $r$.  If $\ell$ is disjoint from $p$, we include the edge from $r$ to
$q$ in $\ell'$.  In order to argue that the right side of
equation~\eqref{e:gv} are the same for $G$ and $G'$,
we check that
$$(-1)^\ell w(\ell) = (-1)^{\ell'} w(\ell').$$
If $\ell$ avoids $p$, the two sides are immediately the same. If $\ell$ meets
$p$, then $(-1)^\ell$ and $(-1)^{\ell'}$ have opposite sign and so do $w(\ell)$
and $w(\ell')$.  The left side of equation~\eqref{e:gv} is also the same:  If
$V$ and $V'$ are the Gessel-Viennot matrices of $G$ and $G'$, $V$ is obtained
from $V'$ by a deleted pivot at $(n+1,n+1)$.

Now suppose that the left and right endpoints do not coincide with the sources
and sinks.  If $G$ has a left endpoint $q$ which is not a source, then there is
an edge $e$ from a vertex $p$ to the vertex $q$.  Let $G'$ be $G$ with $e$
removed and let $V'$ be its Gessel-Viennot matrix.   Since the edge $e$ is not
in any $n$-path in $G$, the graph $G'$ has the same $n$-paths with the same
weights.  If $p$ is the $i$th left endpoint, we can obtain $V'$ from $V$ by
subtracting $w(i,j)$ times row $i$ from $j$, where $w(i,j)$ is the total weight
in $G$ of all paths from $i$ to $j$.  These row operations do not change the
determinant.  The same argument applies if $G$ has a right endpoint which is
not a sink.

Finally if $G$ has a right endpoint source or a left endpoint sink,
then it has no $n$-paths and some row or column of $V$ is 0.
If $G$ has a source or a sink which is not an endpoint,
we can delete it without changing the Gessel-Viennot matrix $V$ or
the set of $n$-paths.
\end{proof}

We call the graph $G'$ constructed in our proof of \thm{th:gv} the
\emph{transit-free resolution of $G$}.  The transit-free resolution is a
connection between the Gessel-Viennot method and the permanent-determinant
method:

\begin{corollary} Let $G$ be a connected, planar, directed, acyclic graph with
$n$ left and right endpoints on the outside face.  Suppose that the left
endpoints are segregated from the right endpoints on this face. If the left
endpoints are the sources and the right endpoints are the sinks, then the
Gessel-Viennot matrix $V$ of $G$ is obtained from a Kasteleyn-Percus matrix $M$
of the transit-free resolution $G'$ of $G$ by deleted pivots.  If not every
left endpoint is a source or not every right endpoint is a sink, $V$ is
obtained by deleted pivots and other matrix operations.
\label{c:gv}
\end{corollary}

Note that by construction the matchings of the transit-free resolution $G'$ of
$G$ are bijective with the $n$-paths in $G$.  The planarity of $G$ together
with the position of its endpoints imply that all $n$-paths induce the same
bijection and therefore have the same sign.

\begin{proof} The Gessel-Viennot matrix $V'$ of the graph $G'$ is obtained from
$V$ by the stated operations.  Thus it suffices to show that $G'$ is planar and
that $V'$ is also a  Kasteleyn-Percus matrix of $G'$.

\begin{fullfigure}{f:lr}{Left-to-right orientation implied by segregation
    of sources and sinks (circled).}
\pspicture(-2,-2)(2,2)
\pcline(-2, 1)(-1, 2)\mto\pcline(-2, 1)(-1, 0)\mto
\pcline(-2,-1)(-1, 0)\mto\pcline(-2,-1)(-1,-2)\mto
\pcline(-1, 2)( 0, 1)\mto\pcline(-1, 0)( 0, 1)\mto
\pcline(-1, 0)( 0,-1)\mto\pcline(-1,-2)( 0,-1)\mto
\pcline( 0, 1)( 1, 2)\mto\pcline( 0, 1)( 1, 0)\mto
\pcline( 0,-1)( 1, 0)\mto\pcline( 0,-1)( 1,-2)\mto
\pcline( 1, 2)( 2, 1)\mto\pcline( 1, 0)( 2, 1)\mto
\pcline( 1, 0)( 2,-1)\mto\pcline( 1,-2)( 2,-1)\mto
\pscircle[fillstyle=solid](-2,1){.2}
\pscircle[fillstyle=solid](-2,-1){.2}
\pscircle[fillstyle=solid]( 2,1){.2}
\pscircle[fillstyle=solid]( 2,-1){.2}
\qdisk(-2, 1){.1}\qdisk(-2,-1){.1}
\qdisk(-1, 2){.1}\qdisk(-1, 0){.1}\qdisk(-1,-2){.1}
\qdisk( 0, 1){.1}\qdisk( 0,-1){.1}
\qdisk( 1, 2){.1}\qdisk( 1, 0){.1}\qdisk( 1,-2){.1}
\qdisk( 2, 1){.1}\qdisk( 2,-1){.1}
\endpspicture
\end{fullfigure}

We first establish that the orientation of $G$ is qualitatively like that of
the example in \fig{f:lr}: the orientations all point from left to right.
More precisely, the edges incident to each transit vertex are segregated, in
the sense that all incoming edges are adjacent and all outgoing edges are
adjacent.  The edges of each internal face are also segregated, in the sense
that the clockwise edges are adjacent and the counterclockwise edges are
adjacent.  To prove that $G$ has this structure, we reallocate the Euler
characteristic of the sphere, $2$, expressed as a sum over elements of $G$.
In this sum, each vertex and face has Euler characteristic $1$ and each edge
has Euler characteristic $-1$.  If a pair of edges shares both a vertex $v$
and a face $f$, we deduct $\frac12$ from the Euler characteristic of $f$ if
the edges both point to or both point from $v$, and otherwise we deduct
$\frac12$ from $v$.  Since each edge participates in $4$ such pairs, these
deductions absorb the total Euler characteristic of all edges.

The reallocated characteristic of a vertex is $1$ if it is a source or sink,
$0$ if it is a segregated transit vertex, and negative otherwise.  The
reallocated characteristic of a face is at most $2-2n$ if it is the outside
face (since orientations must switch between clockwise and counterclockwise
both at the sources and sinks and between them), $0$ if it is a segregated
internal face, and negative otherwise.  (No face has positive reallocated
characteristic since $G$ is acyclic.)  Thus the only way that the total can be
$2$ is if all internal faces and all transit vertices are segregated.

That the transit vertices of $G$ are segregated implies that $G'$ is planar.
That each internal face $f$ is segregated implies that if $f$ has $k$ sides,
the corresponding face $f'$ of $G'$ has $2k-2$ sides.  Moreover the $k-2$ new
edges of $f'$ have weight $-1$ in the proof of \thm{th:gv}, which agrees with
the Kasteleyn-Percus rule.  Thus $V'$ is a Kasteleyn-Percus matrix of $G'$, as
desired.
\end{proof}

Finally we have not discussed a Pfaffian version of the Gessel-Viennot method
defined by Stembridge \cite{Stembridge:paths}. We believe that this method can
be generalized further, and that  it admits an analogue of
Corollary~\ref{c:gv}.

\section{Matchings and Smith normal form}
\label{s:snf}

\subsection{Equivalences of Kasteleyn and Kasteleyn-Percus matrices}
\label{s:invar}

If $M$ is a Kasteleyn-Percus matrix of a bipartite, planar graph $G$, then we
can consider its cokernel, which by \sec{s:matrix} is equinumerous with the
number of matchings of $M$ if it has any matchings. Furthermore, if $\coker M$
is infinite or if $M$ isn't square, we can think of $\coker M$ as a way to
``count'' matchings in a graph that has none. We call such a computation
an \emph{impossible enumeration}. Both observations are reasons to study
$\coker M$ as part of enumerative combinatorics.

If $G$ is weighted by elements of some ring $R$, then we can consider $M$ up to
stable equivalence, whether or not it has a Smith normal form.

Suppose that $M$ and $M'$ are two Kasteleyn-Percus matrices for the same
planar graph $G$.  Then the signs on $G$ given by $M'$ and $M$ differ by a
1-cocycle $c$ with coefficients in the group $\{+,-\}$ \cite{Kuperberg:fun}.
Since the sphere has no first homology, $c = \delta d$, where $d$ is a
0-cochain.  More explicitly $d$ is a function from the vertices of $G$ to
$\{+,-\}$.   We can use $d$ to form two diagonal matrices $A$ and $B$ with
diagonal entries $\pm 1$ and such that $M' = AMB$. Evidently $A$ and $B$ are
invertible over $\Z$, so $M'$ and $M$ have the same cokernel.  In conclusion:

\begin{proposition}  If $G$ be a weighted bipartite planar graph, then all of
its Kasteleyn-Percus matrices $M$ are stably equivalent forms.  In particular
$\coker M$ is an invariant of $G$.
\label{p:inv}
\end{proposition}

\begin{fullfigure}{f:embed}{Embedding-dependent Kasteleyn-Percus cokernels.}
\begin{tabular}{cc}
\pspicture(-2.5,-2)(2.5,1)
\psline(-2,0)(-1,0)\rput[b](-1.5,.2){3}
\pscircle(0,0){1}
\psline(1,0)(2,0)\rput[b](1.5,.2){3}
\qdisk(-2,0){.1}\qdisk(-1,0){.1}\qdisk(1,0){.1}\qdisk(2,0){.1}
\rput[t](0,-1.3){$\Z/9$}
\endpspicture &
\pspicture(-2.5,-2)(2.5,1)
\psline(-2,0)(-1,0)\rput[b](-1.5,.2){3}
\pscircle(0,0){1}
\psline(0,0)(1,0)\rput[b](.5,.2){3}
\qdisk(-2,0){.1}\qdisk(-1,0){.1}\qdisk(0,0){.1}\qdisk(1,0){.1}
\rput[t](0,-1.3){$\Z/3 \oplus \Z/3$}
\endpspicture \\[.75cm]
\pspicture(-2.5,-2)(2.5,1)
\psline(-2,0)(-1,0)\rput[b](-1.5,.2){3}
\pscircle(0,0){1}
\qdisk(-2,0){.1}\qdisk(-1,0){.1}\qdisk(1,0){.1}
\rput[t](0,-1.3){$\Z$}
\endpspicture &
\pspicture(-2.5,-2)(2.5,1)
\psline(-1,0)(0,0)\rput[b](-.5,.2){3}
\pscircle(0,0){1}
\qdisk(-1,0){.1}\qdisk(0,0){.1}\qdisk(1,0){.1}
\rput[t](0,-1.3){$\Z \oplus \Z/3$}
\endpspicture\eatline
\end{tabular}
\end{fullfigure}

\begin{example}  The Smith normal form or cokernel of $M$ can depend on the
embedding of $G$ in the plane.  The top two graphs in \fig{f:embed} have
cokernels $\Z/9$ and $\Z/3 \oplus \Z/3$ in the two embeddings shown.  If $G$
has an odd number of vertices, then it cannot be Kasteleyn flat on its outside
face. In this case changing which face is on the outside can change the
cokernel as well.  The bottom two graphs in \fig{f:embed} are an example.
\end{example}

% Mention Gessel-Viennot-Stembridge

Our analysis generalizes to the non-bipartite case.  If $G$ is
a planar graph with a Kasteleyn matrix $A$, then we can consider
$A$ up to equivalence.

Again all Kasteleyn matrices we choose for the planar graph $G$ are equivalent,
because any two Kasteleyn-flat orientations of $G$ differ by the coboundary of
a 0-cochain on $G$ with values in $\{+,-\}$.  The matrices are consequently
equivalent under the transformation
$$A \mapsto B^TAB$$
for some diagonal matrix $B$ whose non-zero entries are $\pm 1$.  We can also
pass from the usual clockwise-odd Kasteleyn rule to the counterclockwise-odd
rule by negating $A$.  We have no reason to believe that $A$ and $-A$ are
equivalent over a general ground ring $R$, but they do have the same
cokernel and are therefore equivalent if $R$ is a PID.

If $G$ is projectively planar and locally but not
globally bipartite, the argument is slightly different while the conclusion is
the same.  In this case the cohomology group
$$H^1(\R P^2,\Z/2) \cong \Z/2$$
is non-trivial.  Suppose that we have two Kasteleyn-flat orientations of $G$
whose matrices are $A$ and $A'$.  Their discrepancy is a 1-cocycle $c$ which
could represent either the trivial or the non-trivial class in $H^1(\R
P^2,\Z/2)$.  If $c$ is trivial, then
$$A' = B^TAB$$
for some diagonal $B$.  I.e., $A$ and $A'$ are equivalent.  If $c$ is
non-trivial, then
$$A' = -B^TAB,$$
i.e., $A'$ is equivalent to $-A$.

\begin{fullfigure}{f:doublevert}{Preserving Kasteleyn flatness.}
\pspicture(0,-.5)(6.5,.5)
\psline(.7,-.3)(1,0)(.7,.3)\psline(.5,0)(1.5,0)
\psline(1.3,.3)(1,0)(1.3,-.3)
\qdisk(1,0){.1}
\psline{->}(2,0)(3,0)
\psline(3.7,-.3)(4,0)(3.7,.3)
\psline(3.5,0)(4,0)\psline(6,0)(6.5,0)
\pcline(4,0)(5,0)\mto\pcline(6,0)(5,0)\mto
\psline(6.3,.3)(6,0)(6.3,-.3)
\qdisk(4,0){.1}\qdisk(5,0){.1}\qdisk(6,0){.1}
\endpspicture\eatline
\end{fullfigure}

Kasteleyn and Kasteleyn-Percus matrices remain equivalent under more operations than
just the choices of signs or orientations. In particular they remain equivalent
under the moves in Section~\ref{s:polygamy}.  In each move we make a graph $G'$
from the graph $G$, and we need to choose related Kasteleyn-flat orientations
of both graphs.  For example consider a double vertex splitting. If $G$ is
Kasteleyn-flat, and if we orient the two new edges in the splitting in opposite
directions as in \fig{f:doublevert},  then $G'$ is also Kasteleyn flat.  If the
three vertices are numbered $1$, $2$, and $3$, then the matrix $A'$ of $G'$ has
a submatrix of the form
$$\begin{pmatrix} 0 & 1 & 0 \\ -1 & 0 & -1 \\ 0 & 1 & 0 \end{pmatrix}.$$
If we perform a deleted pivot at $(1,2)$ and $(2,1)$,
we reduce $A'$ to the matrix $A$ of $G$.

\subsection{Is it bijective?}
\label{s:bijective}

Whenever two sets are known to have the same size, a traditional question in
combinatorics is whether or not there is a bijection between them.  In this
section we conjecture a relationship between cokernels and matching sets
which is similar to a bijection.

If $M$ is a Kasteleyn-Percus matrix for an unweighted bipartite, planar graph
$G$ with at least one perfect matching, then two such sets to consider are
$\coker M$ and $P$, the set of perfect matchings of
$G$. To this pair we must add a
third set, $\coker M^T$, since the choice between $M$ and $M^T$ is
arbitrary. As explained in \sec{s:smith}, $\coker M$ and $\coker M^T$ are
isomorphic, but there is no canonical isomorphism.  This is evidence against a
natural bijection between $\coker M$ and $\coker M^T$, and therefore a natural
bijection between either of them and $P$.  On the other hand, the special
planar structure of $M$ might yield such bijections.

It may be better to consider quantum bijections or linearized bijections
instead of traditional ones.  If $A$ and $B$ are two finite sets,
a \emph{quantum bijection} is a unitary isomorphism
$$\C[A] \cong \C[B]$$
between the formal linear spans of $A$ and $B$. A quantum bijection can be
implemented by a quantum computer algorithm just as a traditional bijection can
be implemented on a standard computer \cite{Steane:review}.  A linear bijection is a linear
isomorphism
$$\F[A] \cong \F[B],$$
not necessarily unitary, for some field $\F$.  A linear bijection does not have
the empirical computational interpretation that a traditional bijection or a
quantum bijection does, but as a means of proving that $A$ and $B$ are
equinumerous, it can be considered constructive.

If $M$ is a non-singular $n \times n$ matrix over $\Z$, then there is a natural
quantum bijection between $\coker M$ and $\coker M^T$, namely the discrete
Fourier transform.  (It is also a special case of Pontryagin duality
\cite{Rudin:fourier}).  We express it by defining a unitary matrix $U$ whose
rows are indexed by $x \in \coker M$ and whose columns are indexed by $y \in
\coker M^T$. Given such $x$ and $y$, we let $X$ and $Y$ be lifts in $\Z^n$. We
then define
$$U_{x,y} = \frac{\exp(2\pi i Y^T M^{-1} X)}{\sqrt{|\det M|}}.$$
It is easy to check that $Y^T M^{-1} X$ changes by an integer if we change the
lift $X$ of $x$, because two such lifts differ by an element in $\im M$.

Given $M$, $G$, and $P$ as above, it might be possible to factor the unitary
map $U$ into maps to and from $\C[P]$.  However we may need to further relax
the notion of a bijection.   Sometimes when $G$ is a finite group equinumerous
with a finite set $S$, there is no natural bijection between them, but instead
there is a natural, freely transitive group action of $G$ on $S$.  Having
introduced quantum bijections, we can try to make $\C[P]$ a free unitary module
over the group algebras  $\C[\coker M]$ and $\C[\coker M^T]$.  We can even ask
that the two group actions be compatible with $U$ by requiring the commutation
relations
$$\alpha_y \alpha_x = \exp(2\pi i Y^T M^{-1} X)\alpha_x \alpha_y,$$
where $x \in \coker M$ and $y \in \coker M^T$ and $\alpha_x$ and $\alpha_y$ are
their hypothetical actions on $\C[P]$.  A standard theorem in representation
theory says that for any $M$ the algebra
$$D = \C[\coker M] \tensor \C[\coker M^T]$$
twisted by this commutation relation is
isomorphic to a matrix algebra.  This means that $D$ has only one irreducible
representation, and we conjecture that $\C[P]$ has the structure
of this representation.

If $A$ is a non-singular alternating matrix, then we can define a similar
algebra $D$ as a deformation of the group algebra $\C[\coker A]$. We let $D$ be
the formal complex span of elements $\alpha_x$ with $x \in \coker A$, and
we arbitrarily order the elements in $\coker A$.  For $x \le y \in \coker A$,
we define
$$\alpha_x \alpha_y = \alpha_{x+y},$$
and for arbitrary $x$ and $y$, we impose the relation
$$\alpha_y \alpha_x = \exp(2\pi i Y^T A^{-1} X) \alpha_x \alpha_y.$$
The algebra $D$ is again isomorphic to a matrix algebra, since
\thm{th:asmith} allows us to put $A$ into
$$A = \left(\begin{array}{c|c} 0 & M \\ \hline -M & 0 \end{array}\right).$$
If we do so then algebra $D$ then has the form previously described.

\begin{conjecture} If $A$ is a Kasteleyn matrix of a planar graph $G$
with non-empty matching set $P$, then there is a natural action of
the algebra $D$ on $\C[P]$, possibly depending on the way that $G$
is embedded in the plane.
\label{c:action}
\end{conjecture}

\section{Lozenge and domino tilings}
\label{s:lozdom}

\subsection{Plane partitions and lozenge tilings}
\label{s:pp}

Plane partitions are an interesting source of enumerative planar matching
problems.  We consider the cokernels and Smith normal forms that arise in these
problems, relying on the material in References~\citealp{Kuperberg:perdet} and
\citealp{Kuperberg:fun}.

\begin{fullfigure}{f:pptil}{A plane partition and a tiling.}
\psset{xunit=.5cm,yunit=.577cm}
\pspicture(-7,0)(7,5)
\rput[b](-4.5,0){\pspicture(-2,0)(2,5)
\psset{fillstyle=solid}
\pspolygon[fillcolor=lightgray](-1,4.5)(-1,3.5)(0,3)(0,4)
\pspolygon[fillcolor=darkgray](1,4.5)(1,3.5)(0,3)(0,4)
\pspolygon[fillcolor=lightgray](-1,3.5)(-1,2.5)(0,2)(0,3)
\pspolygon[fillcolor=lightgray](0,3)(0,2)(1,1.5)(1,2.5)
\pspolygon[fillcolor=darkgray](2,3)(2,2)(1,1.5)(1,2.5)
\pspolygon[fillcolor=lightgray](0,2)(0,1)(1,.5)(1,1.5)
\pspolygon[fillcolor=darkgray](2,2)(2,1)(1,.5)(1,1.5)
\pspolygon[fillcolor=lightgray](-2,2)(-2,1)(-1,.5)(-1,1.5)
\pspolygon[fillcolor=darkgray](0,2)(0,1)(-1,.5)(-1,1.5)
\pspolygon[fillcolor=gray](-1,4.5)(0,4)(1,4.5)(0,5)
\pspolygon[fillcolor=gray](0,3)(1,2.5)(2,3)(1,3.5)
\pspolygon[fillcolor=gray](-2,2)(-1,1.5)(0,2)(-1,2.5)
\psset{fillstyle=none}
\psline[linestyle=dashed](-2,2)(-2,4)(-1,4.5)
\psline[linestyle=dashed](1,4.5)(2,4)(2,3)
\psline[linestyle=dashed](-1,.5)(0,0)(1,.5)(0,1)
\pcline[linestyle=none](-2,1)(-2,4)\Aput{$c$}
\pcline[linestyle=none](0,0)(-2,1)\Aput{$b$}
\pcline[linestyle=none](0,0)(2,1)\Bput{$a$}
\endpspicture}
\rput[b](4.5,0){\pspicture(-2,0)(2,5)
\pspolygon(-1,4.5)(-1,3.5)(0,3)(0,4)
\pspolygon(1,4.5)(1,3.5)(0,3)(0,4)
\pspolygon(-1,3.5)(-1,2.5)(0,2)(0,3)
\pspolygon(0,3)(0,2)(1,1.5)(1,2.5)
\pspolygon(2,3)(2,2)(1,1.5)(1,2.5)
\pspolygon(0,2)(0,1)(1,.5)(1,1.5)
\pspolygon(2,2)(2,1)(1,.5)(1,1.5)
\pspolygon(-2,2)(-2,1)(-1,.5)(-1,1.5)
\pspolygon(0,2)(0,1)(-1,.5)(-1,1.5)
\pspolygon(-1,4.5)(0,4)(1,4.5)(0,5)
\pspolygon(0,3)(1,2.5)(2,3)(1,3.5)
\pspolygon(-2,2)(-1,1.5)(0,2)(-1,2.5)
\psline(-2,2)(-2,4)(-1,4.5)
\psline(1,4.5)(2,4)(2,3)
\psline(-1,.5)(0,0)(1,.5)(0,1)
\psline(-2,3)(-1,3.5)
\pcline[linestyle=none](-2,1)(-2,4)\Aput{$c$}
\pcline[linestyle=none](0,0)(-2,1)\Aput{$b$}
\pcline[linestyle=none](0,0)(2,1)\Bput{$a$}
\endpspicture}
\psline{->}(-1,2.5)(1,2.5)
\endpspicture
\end{fullfigure}

\begin{fullfigure}{f:z223}{The graph $Z(2,2,3)$.}
\psset{xunit=.289cm,yunit=.5cm}
\pspicture(-6,1)(6,9)
\multips(-4,2)(0,2){4}{\qline(0,0)(2,0)}  % Horizontal lines
\multips(-1,1)(0,2){5}{\qline(0,0)(2,0)}
\multips( 2,2)(0,2){4}{\qline(0,0)(2,0)}
\multips(-4,2)(0,2){3}{\qline(0,0)(-1,1)} % NW lines
\multips(-1,1)(0,2){4}{\qline(0,0)(-1,1)}
\multips( 2,2)(0,2){4}{\qline(0,0)(-1,1)}
\multips( 5,3)(0,2){3}{\qline(0,0)(-1,1)}
\multips( 4,2)(0,2){3}{\qline(0,0)( 1,1)} % NE lines
\multips( 1,1)(0,2){4}{\qline(0,0)( 1,1)}
\multips(-2,2)(0,2){4}{\qline(0,0)( 1,1)}
\multips(-5,3)(0,2){3}{\qline(0,0)( 1,1)}
% \qline(-1,1)( 1,1) \qline(-5,3)(-4,2)
% \qline(-2,2)(-1,3) \qline( 1,3)( 2,2)
% \qline( 4,2)( 5,3) \qline(-4,4)(-2,4)
% \qline( 1,5)( 2,4) \qline( 4,4)( 5,5)
% \qline(-5,5)(-4,6) \qline(-2,6)(-1,5)
% \qline( 2,6)( 4,6) \qline(-5,7)(-4,8)
% \qline(-2,8)(-1,7) \qline( 1,7)( 2,8)
% \qline( 4,8)( 5,7) \qline(-1,9)( 1,9)
\multips(-5,3)(0,2){3}{\qdisk(0,0){.1}}\multips(-2,2)(0,2){4}{\qdisk(0,0){.1}}
\multips( 1,1)(0,2){5}{\qdisk(0,0){.1}}\multips( 4,2)(0,2){4}{\qdisk(0,0){.1}}
\multips( 5,3)(0,2){3}{\qdisk(0,0){.1}}\multips( 2,2)(0,2){4}{\qdisk(0,0){.1}}
\multips(-1,1)(0,2){5}{\qdisk(0,0){.1}}\multips(-4,2)(0,2){4}{\qdisk(0,0){.1}}
\endpspicture
\end{fullfigure}

A plane partition in an $a \times b \times c$ box is equivalent to a lozenge
tiling of an $(a,b,c)$-semiregular hexagon (\fig{f:pptil}), which in
turn is equivalent to a perfect matching of the dual hexagonal graph
$Z(a,b,c)$ (\fig{f:z223}).

If a group $G$ acts on the box and the plane partitions inside it, it also acts
on the graph $Z(a,b,c)$.  The $G$-invariant matchings correspond to matchings
of a modified quotient graph $Z_G(a,b,c)$.  To understand these
graphs we recall the three generators of $G$:
\begin{description}
\item[$\bullet$] $\rho$, cyclic symmetry for plane partitions or
rotation by 120 degrees for lozenge tilings, defined when $a=b=c$.
\item[$\bullet$] $\tau$, symmetry for plane partitions or diagonal
reflection for lozenge tilings, defined when $b=c$.
\item[$\bullet$] $\kappa$, complementation for plane partitions or
rotation by 180 degrees for lozenge tilings.
\end{description}
We describe $Z_G(a,b,c)$ case by case:
\begin{description}
\item[$\bullet$] If $G = \braket{\rho}$ or $\braket{\rho,\kappa}$, or if $a$,
$b$, and $c$ are all even and $G$ is $\braket{\kappa}$, then $Z_G(a,b,c)$
is the usual quotient graph $Z(a,b,c)/G$.
\item[$\bullet$] If $G = \braket{\kappa\tau}$ or $G =
\braket{\kappa\tau,\rho}$, then we delete the edges and vertices of $Z(a,b,c)$
along the lines of reflection and let $Z_G(a,b,c)$ be a connected component of
the remainder.
\item[$\bullet$] If $G = \braket{\kappa}$ and only one or two of $a$, $b$, and
$c$ is even,  then $Z(a,b,c)$ has a central edge $e$ invariant under $\kappa$.
If one dimension is even, we define $Z_\kappa(a,b,c)$ by deleting $e$ and its
vertices and then quotienting by $\kappa$. If two dimensions are even, we
define $Z_\kappa(a,b,c)$ by deleting $e$ but not its vertices, and then
quotienting by $\kappa$.
\item[$\bullet$] If $G = \braket{\tau}$, $\braket{\tau,\kappa}$, or
$\braket{\tau,\rho,\kappa}$, we start with $Z_H(a,b,c)$, where $H$ is,
respectively, $\braket{1}$, $\braket{\tau\kappa}$, or
$\braket{\rho,\tau\kappa}$. We cut $Z_H(a,b,c)$ by the line of reflection, and
tie the cut edges of one region to a polygamous vertex to define $Z_G(a,b,c)$.
\item[$\bullet$] If $G = \braket{\tau,\rho}$, we cut $Z(a,a,a)$ by three lines
of reflection and tie the cut edges of one region (lying along two of the
three lines) to a polygamous vertex to form $Z_G(a,a,a)$.
\end{description}

\begin{fullfigure}{f:qz223}{The graph $Z(2,2,3)$ weighted for $q$-enumeration.}
\psset{xunit=.289cm,yunit=.5cm}
\pspicture(-6,1)(6,9)
\multips(-4,2)(0,2){4}{\qline(0,0)(2,0)}  % Horizontal lines
\multips(-1,1)(0,2){5}{\qline(0,0)(2,0)}
\multips( 2,2)(0,2){4}{\qline(0,0)(2,0)}
\multips(-4,2)(0,2){3}{\qline(0,0)(-1,1)} % NW lines
\multips(-1,1)(0,2){4}{\qline(0,0)(-1,1)}
\multips( 2,2)(0,2){4}{\qline(0,0)(-1,1)}
\multips( 5,3)(0,2){3}{\qline(0,0)(-1,1)}
\multips( 4,2)(0,2){3}{\qline(0,0)( 1,1)} % NE lines
\multips( 1,1)(0,2){4}{\qline(0,0)( 1,1)}
\multips(-2,2)(0,2){4}{\qline(0,0)( 1,1)}
\multips(-5,3)(0,2){3}{\qline(0,0)( 1,1)}
\qline(-1,1)( 1,1) \qline(-5,3)(-4,2)
\qline(-2,2)(-1,3) \qline( 1,3)( 2,2)
\qline( 4,2)( 5,3) \qline(-4,4)(-2,4)
\qline( 1,5)( 2,4) \qline( 4,4)( 5,5)
\qline(-5,5)(-4,6) \qline(-2,6)(-1,5)
\qline( 2,6)( 4,6) \qline(-5,7)(-4,8)
\qline(-2,8)(-1,7) \qline( 1,7)( 2,8)
\qline( 4,8)( 5,7) \qline(-1,9)( 1,9)
\multips(-5,3)(0,2){3}{\qdisk(0,0){.1}}\multips(-2,2)(0,2){4}{\qdisk(0,0){.1}}
\multips( 1,1)(0,2){5}{\qdisk(0,0){.1}}\multips( 4,2)(0,2){4}{\qdisk(0,0){.1}}
\multips( 5,3)(0,2){3}{\qdisk(0,0){.1}}\multips( 2,2)(0,2){4}{\qdisk(0,0){.1}}
\multips(-1,1)(0,2){5}{\qdisk(0,0){.1}}\multips(-4,2)(0,2){4}{\qdisk(0,0){.1}}
\rput[b](-3,8.2){$q^3$} \rput[b](-3,6.2){$q^2$} \rput[b](-3,4.2){$q$}
\rput[b](-3,2.2){$1$}   \rput[b](0,9.2){$q^4$}  \rput[b](0,7.2){$q^3$}
\rput[b](0,5.2){$q^2$}  \rput[b](0,3.2){$q$}    \rput[b](0,1.2){$1$}
\rput[b](3,8.2){$q^3$}  \rput[b](3,6.2){$q^2$}  \rput[b](3,4.2){$q$}
\rput[b](3,2.2){$1$}
\endpspicture
\end{fullfigure}

For every symmetry group $G$, the number of $G$-invariant plane partitions
$N_G(a,b,c)$ is \emph{round}, meaning a product of small factors.  (This is not
a completely rigorous notion.  In this case $N_G(a,b,c)$ grows exponentially in
$ab+ac+bc$ while its prime factors grow linearly in $a+b+c$.) In addition if
$G$ is a subgroup of $\braket{\rho,\tau}$, the $G$-invariant partitions have
round $q$-enumerations, where the $q$-weight of a plane partition is sometimes
the number of cubes and sometimes the number of $G$-orbits of cubes.  (To say
that a polynomial $P(q)$ is round means not only that it is a product of small
factors, but also that the factors are cyclotomic.  Equivalently $P(q)$ is a
ratio of products of differences of monomials.)  All of these enumerations are
proven \cite{Stanley:symmetries,Kuperberg:perdet,%
Andrews:tsscpp,Stembridge:enumeration} except for the conjectured orbit
$q$-enumeration of totally symmetric plane partitions.  Both orbit and cube
$q$-enumerations can be realized by weighted enumerations of matchings in
$Z_G(a,b,c)$ \cite{Kuperberg:perdet,Kuperberg:fun}.  \fig{f:qz223} shows an
example where $G$ is trivial (so that there is no distinction between cube and
orbit $q$-enumeration in this case).   Also the weight of a matching in the
example only agrees with the $q$-weight of the corresponding plane partition up
to a (matching-independent) factor of $q$.  We will therefore consider
$q$-enumerations over the ring $\Z[q,q^{-1}]$ and absorb powers of $q$ in
normalization.

We let $Z_G(a,b,c;q)$ be $Z_G(a,b,c)$ with weights chosen for
cube $q$-enumeration, and we let $\tZ_G(a,b,c;q)$ be $Z_G(a,b,c)$
with weights chosen for orbit $q$-enumeration.

\begin{fullfigure}{f:lmregion}{A lozenge tiling of a region with $a=4$,
    $\lambda=(2,2)$, and $\mu=(1)$.}
\psset{xunit=.75cm,yunit=.650cm}
\pspicture(-2,0)(4,5)
\pspolygon[fillstyle=solid,fillcolor=gray](-2,4)(-1,4)(-1.5,3)
\pspolygon[fillstyle=solid,fillcolor=gray](0,4)(1,4)(.5,3)
\pspolygon[fillstyle=solid,fillcolor=gray](2,0)(2.5,1)(3,0)
\pspolygon[fillstyle=solid,fillcolor=gray](3,0)(3.5,1)(4,0)
\psline(-1,4)(-1.5,3)(-.5,3)(0,4)(1.5,1)
\psline(-1,2)(0,2)(1,4)(1.5,3)(2.5,3)(2,2)
\psline(-.5,1)(.5,1)(1.5,3)
\psline(-.5,3)(1,0)(1.5,1)(2.5,1)(3,2)
\psline(1,2)(2,2)(3,0)(3.5,1)
\pspolygon(-2,4)(2,4)(4,0)(0,0)
\rput[t](2,-.4){$\lambda$}
\rput[b](0,4.4){$\mu$}
\rput[lb](3.2,2.2){$a$}
\endpspicture
\end{fullfigure}

\begin{fullfigure}{f:lmweights}{Weights of $Z(\lambda/\mu;\vx)$.}
\psset{xunit=1cm,yunit=.577cm}
\pspicture(-2,.5)(4,6)
\psline(-1,4)(-.5,3.5)
\psline(-.5,2.5)(0,2)
\multips(-1,4)(1,0){4}{\psline(0,0)(0,1)\qdisk(0,0){.1}\qdisk(0,1){.1}}
\multips(-.5,2.5)(1,0){4}{\psline(0,0)(0,1)\qdisk(0,0){.1}\qdisk(0,1){.1}}
\multips(0,1)(1,0){4}{\psline(0,0)(0,1)\qdisk(0,0){.1}\qdisk(0,1){.1}}
\multips(-1,5)(2,0){2}{\psline(0,0)(.5,.5)(1,0)\qdisk(.5,.5){.1}}
\multips(-.5,3.5)(1,0){3}{\psline(0,0)(.5,.5)(1,0)}
\multips(0,2)(1,0){3}{\psline(0,0)(.5,.5)(1,0)}
\multips(0,1)(1,0){2}{\psline(0,0)(.5,-.5)(1,0)\qdisk(.5,-.5){.1}}
\rput[rb](-.8,5.3){$x_4$}\rput[rb](1.2,5.3){$x_4$}
\rput[rb](-.3,3.8){$x_3$}\rput[rb](.7,3.8){$x_3$}\rput[rb](1.7,3.8){$x_3$}
\rput[rb](.2,2.3){$x_2$}\rput[rb](1.2,2.3){$x_2$}\rput[rb](2.2,2.3){$x_2$}
\rput[rb](.7,.8){$x_1$}\rput[rb](1.7,.8){$x_1$}
\endpspicture
\end{fullfigure}


The problem of counting matchings in $Z(a,b,c)$ has two other interesting
generalizations.  The lozenge tilings of a parallelogram strip with notches on
both sides (see \fig{f:lmregion}) are naturally bijective with the
semi-standard skew tableaux of shape $\lambda/\mu$ and parts bounded by some
$a$ \cite[\S7.10]{Stanley:enumerative2}, where $\lambda$ and $\mu$ are two
partitions with $\lambda$ containing $\mu$.  If $\lambda$ has $b$ nonzero
parts, the parallelogram then has dimensions $a$ by $\lambda_1 + b$.  On the
bottom row it has notches at positions $\lambda_i + b+1-i$, counting from the
left.  On the top row it has notches at positions $\mu_i + b+1-i$, counting
from the left and extending $\mu$ by $0$ so that it also has $b$ parts.  We
leave the proof of the bijection between tilings and tableaux to the reader
since it is similar to existing arguments in the literature.  We let
$Z(\lambda/\mu,a)$ be the graph dual to the tiling of this region by triangles,
so that the lozenge tilings correspond to the matchings of $Z(\lambda/\mu,a)$.
In an important weighted enumeration we assign the weight $x_i$ to the
northeast-pointing edges in the $i$th row, as in \fig{f:lmweights}. Call the
weighted graph $Z(\lambda/\mu;\vx)$ The total weight of its matchings is the
skew Schur function $s_{\lambda/\mu}(\vx)$ (in finitely many variables).  If we
let
$$\vq_a = (1,q,\ldots,q^{a-1}),$$
then the specialization $s_{\lambda/\mu}(\vq_a)$ is the standard $q$-enumeration
of skew tableaux.  In particular, if we omit $\mu$ (by setting it to the empty
partition), then $s_\lambda(\vx)$ is the character of an irreducible
representation $V(\lambda)$ of $\GL(a,\C)$, while $s_\lambda(\vq_a)$ is round by
the $q$-Weyl dimension formula.

A second generalization is to count tilings of a semiregular hexagon with side
lengths $a,b+d,c,a+d,b,c+d$ and with a triangle of size $d$ removed
\cite{CEKZ:triangular}.  We do not know of a $q$-enumeration of these, although
the symmetry $\kappa\tau$ (corresponding to TCPPs) appears when $b=c$ and the
symmetry $\rho$ (corresponding to CSPPs) appears when $a=b=c$.  We let
$Z(a,b,c,d,d)$ be the dual graph and we analogously
define $Z_G(a,b,c,d,d)$ if $G$ is a subgroup of
$\braket{\kappa\tau,\rho}$.

\begin{fullfigure}{f:hextriang}{Hexagonal regions without central triangles.}
\psset{xunit=.75cm,yunit=.650cm}
\pspicture(-.5,-1)(11,5)
\pspolygon(0,1)(.5,0)(3.5,0)(4,1)(2.5,4)(1.5,4)
\pspolygon(1,1)(3,1)(2,3)
\uput[30](3.25,2.5){$b+d$}\uput[90](2,4){$a$}
\uput[150](.75,2.5){$c+d$}\uput[210](.25,.5){$b$}
\uput[270](2,0){$a+d$}\uput[330](3.75,.5){$c$}
\uput[330](1.5,2){$e$}
\pspolygon(6,1)(6.5,0)(9.5,0)(10,1)(8.5,4)(7.5,4)
\pspolygon(8,1)(8.5,2)(7.5,2)
\uput[30](9.25,2.5){$b$}\uput[90](8,4){$a+d$}
\uput[150](6.75,2.5){$c$}\uput[210](6.25,.5){$b+d$}
\uput[270](8,0){$a$}\uput[330](9.75,.5){$c+d$}
\rput(8,1.667){$e$}
\endpspicture\eatline
\end{fullfigure}

As we mentioned in \sec{s:snf}, we can consider the Kasteleyn or
Kasteleyn-Percus cokernel for impossible enumerations where there are no
matchings.  This allows us to vary the above graphs in several ways, which we
describe case by case:
\begin{description}
\item[$\bullet$] We can consider $Z_\kappa(a,b,c)$ when all three of $a$, $b$,
and $c$ are odd, as well as $Z_\braket{\kappa,\rho}(a,a,a)$ when $a$ is odd.
\item[$\bullet$] If one of $a$, $b$, and $c$ is odd, we define the graph
$Z'_\kappa(a,b,c)$ by removing the central edge $e$ but not its vertices before
quotienting by $\kappa$.  If two are odd we define $Z'_\kappa(a,b,c)$ by
removing $e$ and its vertices before quotienting by $\kappa$.
\item[$\bullet$] If $Z_G(a,b,c)$ has a polygamous vertex, we can give it the
wrong parity to make $Z'_G(a,b,c)$.  If $G = \braket{\tau}$ or
$G = \braket{\rho,\tau}$, then we also define the $q$-weighted forms
$Z'_G(a,b,c;q)$ and $\tZ'_G(a,b,c;q)$.
\item[$\bullet$] We define the graph $Z(a,b,c,d,e)$ by removing a triangle of
size $e$ from a semiregular hexagon of side lengths $a,b+d,c,a+d,b,c+d$, with
$d \ne e$, as shown in \fig{f:hextriang}.  The parameters $d$ and $e$ might
even have opposite sign, which we interpret by turning the triangle
upside-down, as also indicated in \fig{f:hextriang}.
\end{description}

For each of the graphs defined in this section, we denote a corresponding
Kasteleyn-Percus matrix by replacing $Z$ by $M$ if it is bipartite and
monogamous, and the corresponding Kasteleyn matrix by replacing $Z$ by $A$
otherwise.

\begin{conjecture} Each of the matrices $M(a,b,c;q)$, $M_\rho(a,a,a;q)$,
$A_\tau(a,b,b;q)$, $\tA_\tau(a,b,b;q)$, $A'_\tau(a,a,b;q)$,
$\tA'_\tau(a,a,b;q)$, $\tA_\braket{\rho,\tau}(a,a,a;q)$,
$\tA'_\braket{\rho,\tau}(a,a,a;q)$, and $M(\mu;\vq_a)$ admits a Smith normal
form over $\Z[q,q^{-1}]$, and the entries are $q$-round.  The Smith normal form
over $\Z$ of each of the matrices $M(a,b,c,d,e)$, $M_{\kappa\tau}(2a,b,b)$,
$M_\braket{\rho,\kappa\tau}(2a,2a,2a)$, $A_\kappa(a,b,c)$, $A'_\kappa(a,b,c)$,
$A_\braket{\kappa,\tau}(2a,b,b)$, $A'_\braket{\kappa,\tau}(2a,b,b)$,
$A_\braket{\rho,\kappa}(a,a,a)$, $A_\braket{\rho,\kappa,\tau}(2a,2a,2a)$, and
$A'_\braket{\rho,\kappa,\tau}(2a,2a,2a)$ has round entries.
\label{c:round}
\end{conjecture}

We could have stated conjecture~\ref{c:round} in greater generality by
combining more of the variations above.  For example the graph $Z(a,a,a,d,e)$
has symmetries and we could consider the matrix of a suitably modified quotient
graph.  Indeed we do not know how to state Conjecture~\ref{c:round} in full
generality, since there are yet other variations of counting lozenge tilings in
a hexagon with round enumerations \cite{CK:centered}.  Presumably many or all
of these variations also have impossible counterparts, and some may have
$q$-enumerations as well.  Also the spirit of the conjecture is to find the
Smith normal forms or the cokernels explicitly.

\begin{conjecture} The Smith normal forms over $\Z[q,q^{-1}]$ of each of the
matrices $M(a,b,c;q)$, $M_\rho(a,a,a;q)$, $A_\tau(a,b,b;q)$,
$\tA_\tau(a,b,b;q)$, and $\tA_\braket{\rho,\tau}(a,a,a;q)$ are square free.
\label{c:sqfree}
\end{conjecture}

Conjecture~\ref{c:sqfree} may also not be fully general, although we note that
the Smith normal form of $M(\lambda;\vq_a)$ is not always square free. Note
that Conjectures~\ref{c:sqfree} and \ref{c:round} would together solve problem
5 in Propp's problem list \cite{Propp:progress}, which asks for the Kasteleyn
cokernel of the graph $Z(a,b,c)$.  The reason is that the Smith normal form of
any non-singular matrix $M$ is uniquely determined by $\det M$, provided that
the normal form exists and is square free. For example the $q$-enumeration of
plane partitions tells us that
$$\det M(2,2,2;q) = (2)_q^2(5)_q,$$
where
$$(n)_q = \frac{q^n-1}{q-1}.$$
So Conjectures \ref{c:round} and \ref{c:sqfree} assert that $\Sm(M(2,2,2;q))$
exists and its nontrivial entries are $(2)_q$ and $(2)_q(5)_q$.  If we
specialize at $q=1$, we obtain the correct prediction that
$$\coker M(2,2,2) \cong \Z/2\oplus \Z/10.$$

Stembridge~\cite{Stembridge:q-1} noticed a family of relations, called the
$q=-1$ phenomenon, between $-1$-enumeration of some symmetry classes of plane
partitions and ordinary enumeration of other symmetry classes. We conjecture an
extension of the phenomenon that is easier to state in terms of cokernels in
some cases and Smith normal forms in others.

\begin{conjecture} If $G$ is $\braket{1}$ or $\braket{\rho}$ and if $G' =
\braket{G,\kappa}$, then
$$\Sm(A_{G'}(a,b,c)) = \Sm(M_G(a,b,c)_{-1})^2.$$
If $G$ is $\braket{\tau}$ or $\braket{\rho,\tau}$, and if $G'$ is,
respectively, $\braket{\kappa\tau}$ or $\braket{\rho,\kappa\tau}$, then
$$\coker A_G(a,b,c)_{-1} \cong {\coker M_{G'}(a,b,c)}^{\oplus 2}.$$
If $G$ is $\braket{\tau}$ or $\braket{\rho,\tau}$ and if $G' =
\braket{G,\kappa}$, then
$$\coker A_{G'}(a,b,c) \cong \coker A'_G(a,b,c)_{-1}.$$
\label{c:q-1}
\end{conjecture}

\subsection{Jacobi-Trudi matrices}
\label{s:jt}

One conclusion of our construction for skew tableaux is a novel
determinant formula for skew Schur functions:
$$s_{\lambda/\mu}(\vx) = \det M(\lambda/\mu;\vx).$$
We can compare this to two other determinant formulas for skew
Schur functions \cite[\S7.16]{Stanley:enumerative2}. Let
$$J(\lambda/\mu;\vx)_{i,j} = h_{\lambda_i-\mu_j-i+j}(\vx),$$
where $h_n(\vx)$ is the $n$th complete symmetric function of $\vx$,
and let
$$D(\lambda/\mu;\vx)_{i,j} = e_{\lambda'_i-\mu'_j-i+j}(\vx),$$
where $e_n(\vx)$ is the $n$th elementary symmetric function of $\vx$
and $\lambda'$ is the partition conjugate to $\lambda$.
Then the Jacobi-Trudi identity states that
$$s_{\lambda/\mu}(\vx) = \det J(\lambda/\mu;\vx)$$
while the dual Jacobi-Trudi identity states that
$$s_{\lambda/\mu}(\vx) = \det D(\lambda/\mu;\vx).$$

\begin{theorem} The Jacobi-Trudi matrices $J(\lambda/\mu;\vx)$ and
$D(\lambda/\mu;\vx)$ are stably equivalent over the ring $\Z[\vx]$ to the
matrix $M(\lambda/\mu;\vx)$.
\label{th:jt}
\end{theorem}

\begin{fullfigure}{f:lmsquare}{First Gessel-Viennot model of lozenge tilings.
    (Not all orientations are shown.)}
\psset{xunit=1cm,yunit=1cm}
\pspicture(0,-.5)(3.5,4)
\multips(0,0)(1,0){4}{\psline(0,0)(0,3)}
\multips(0,0)(0,1){4}{\psline(0,0)(3,0)}
\pcline(0,3)(1,3)\mto\pcline(1,3)(1,2)\mto
\pcline(0,3)(0,2)\mto\pcline(0,2)(1,2)\mto
\pscircle[fillstyle=solid](0,3){.2}\pscircle[fillstyle=solid](2,3){.2}
\pscircle[fillstyle=solid](2,0){.2}\pscircle[fillstyle=solid](3,0){.2}
\multips(0,0)(1,0){4}{\qdisk(0,0){.1}}\multips(0,1)(1,0){4}{\qdisk(0,0){.1}}
\multips(0,2)(1,0){4}{\qdisk(0,0){.1}}\multips(0,3)(1,0){4}{\qdisk(0,0){.1}}
\rput[b](.5,3.1){$x_4$}\rput[b](1.5,3.1){$x_4$}\rput[b](2.5,3.1){$x_4$}
\rput[b](.5,2.1){$x_3$}\rput[b](1.5,2.1){$x_3$}\rput[b](2.5,2.1){$x_3$}
\rput[b](.5,1.1){$x_2$}\rput[b](1.5,1.1){$x_2$}\rput[b](2.5,1.1){$x_2$}
\rput[b](.5, .1){$x_1$}\rput[b](1.5, .1){$x_1$}\rput[b](2.5, .1){$x_1$}
\rput[t](1.5,-.5){$\lambda$}\rput[t](1.5,4){$\mu$}\rput[l](3.3,1.5){$a-1$}
\endpspicture
\end{fullfigure}

\begin{proof} The theorem is a special case of Corollary \ref{c:gv}.  Let
$X(\lambda/\mu;\vx)$ be the graph exemplified in \fig{f:lmsquare}:  a square
grid of height $a-1$ and width $\lambda_1+b$.  On the top there is a left
endpoint at each position $\mu_i+b+1-i$ and on the bottom a right endpoint at
each position $\lambda_i+b+1-i$.  Each horizontal edge points to the right and
on the $i$th row has weight $x_i$.  Each vertical edge points down.  By a
standard argument the Gessel-Viennot matrix of $X(\lambda/\mu;\vx)$ is
$J(\lambda/\mu;\vx)$. At the same time, one can check that the transit-free
resolution of $X(\lambda/\mu;\vx)$ is $Z(\lambda/\mu;\vx)$.  Thus Corollary
\ref{c:gv} says that $J(\lambda/\mu;\vx)$ is equivalent to
$M(\lambda/\mu;\vx)$.

\begin{fullfigure}{f:lmdiamond}{Second Gessel-Viennot model of lozenge tilings.
    (Not all orientations are shown.)}
\pspicture(0,-.5)(10,4.8)
\multips(0,4)(2,0){4}{\psline(0,0)(4,-4)}
\psline(1,3)(2,4)\psline(2,2)(4,4)\psline(3,1)(6,4)
\psline(4,0)(7,3)\psline(6,0)(8,2)\psline(8,0)(9,1)
\pcline(2,4)(1,3)\mto\pcline(0,4)(1,3)\mto
\pscircle[fillstyle=solid](2,4){.2}\pscircle[fillstyle=solid](6,4){.2}
\pscircle[fillstyle=solid](4,0){.2}\pscircle[fillstyle=solid](6,0){.2}
\multips(0,4)(1,-1){5}{\qdisk(0,0){.1}}
\multips(2,4)(1,-1){5}{\qdisk(0,0){.1}}
\multips(4,4)(1,-1){5}{\qdisk(0,0){.1}}
\multips(6,4)(1,-1){5}{\qdisk(0,0){.1}}
\rput[br](1.4,3.6){$x_4$}\rput[br](3.4,3.6){$x_4$}\rput[br](5.4,3.6){$x_4$}
\rput[br](2.4,2.6){$x_3$}\rput[br](4.4,2.6){$x_3$}\rput[br](6.4,2.6){$x_3$}
\rput[br](3.4,1.6){$x_2$}\rput[br](5.4,1.6){$x_2$}\rput[br](7.4,1.6){$x_2$}
\rput[br](4.4, .6){$x_1$}\rput[br](6.4, .6){$x_1$}\rput[br](8.4, .6){$x_1$}
\rput[bl](8.3,2.3){$a$}\rput[b](3,4.5){$\mu'$}\rput[t](7,-.5){$\lambda'$}
\endpspicture
\end{fullfigure}

Let $Y(\lambda/\mu;\vx)$ be the graph exemplified in \fig{f:lmdiamond}. It is a
diamond grid of height $a$ and width $\lambda_1+b$.  All edges point down, and
those in the $i$th row that point southwest have weight $x_i$.  On the top row
there is a left endpoint at each position $b+i-\mu'_i$ and on the bottom a
right endpoint at each position $b+i-\lambda'_i$.  Note that the left endpoints
are at all of the positions \emph{not} of the form $\mu_i+b+1-i$ and likewise
the right endpoints are at the positions \emph{not} of the form One can check
that the Gessel-Viennot matrix of $X(\lambda/\mu;\vx)$ is
$D(\lambda/\mu;\vx)$.  At the same time, noting the gaps between the marked
endpoints,  one can check that the transit-free resolution of
$Y(\lambda/\mu;\vx)$ is $Z(\lambda/\mu;\vx)$. Thus Corollary \ref{c:gv} says
that $J(\lambda/\mu;\vx)$ is equivalent to $D(\lambda/\mu;\vx)$.
\end{proof}

\begin{question} Are $J(\lambda/\mu;\vx)$ and $D(\lambda/\mu;\vx)$
stably equivalent over the ring of symmetric functions?
\end{question}

\thm{th:jt} implies that there are several ways that equivalent forms of the
matrix $M(\lambda/\mu;\vx)$ arise in several common guises.  If we set
$\vx=\vq_a$ and $\mu=0$, then  Conjecture~\ref{c:round} asserts that 
$M(\lambda;\vq_a)$ admits a Smith normal form  a Smith normal form over the
ring $\Z[q,q^{-1}]$. This suggests that $\coker M(\lambda;\vq_a)$ is an
important extra structure that one can associate to the representation
$V(\lambda)$ mentioned previously.  Moreover the relationship between
$M(\lambda)$ and $V(\lambda)$ is an interesting special case of
Conjecture~\ref{c:action}.

\subsection{Domino tilings}
\label{s:domino}

\begin{fullfigure}{f:aztec}{An Aztec diamond of order 3}
\pspicture(-3,-3)(3,3)
\pspolygon(-1,3)(1,3)(1,2)(2,2)(2,1)(3,1)(3,-1)(2,-1)(2,-2)(1,-2)(1,-3)
    (-1,-3)(-1,-2)(-2,-2)(-2,-1)(-3,-1)(-3,1)(-2,1)(-2,2)(-1,2)
\pspolygon[linestyle=dashed](-2,-1)(-2,1)(2,1)(2,-1)
\pspolygon[linestyle=dashed](-1,-2)(-1,2)(1,2)(1,-2)
\psline[linestyle=dashed](0,-3)(0,3)
\psline[linestyle=dashed](-3,0)(3,0)
\endpspicture
\end{fullfigure}

Domino tilings of an Aztec diamond are a well-known analogue of lozenge tilings
of a hexagon.  Recall that an Aztec diamond of order $n$ is the polyomino
consisting of those unit squares lying entirely inside the region $|x|+|y|
\le n+1$, as shown in \fig{f:aztec}. A domino tiling of an Aztec diamond
corresponds to a matching of the graph dual to the tiling by squares; an
example of such a graph is the one on the left in \fig{f:polytied}.  Denote
this graph by $Z_A(n)$ and let $M_A(n)$ be a Kasteleyn-Percus matrix for it.

\begin{theorem} If $M_A(n)$ is a Kasteleyn-Percus matrix for
domino tilings of an Aztec diamond of order $n$, then
$$\coker M_A(n) \cong \Z/2 \oplus \Z/4 \oplus \dots \oplus \Z/2^n.$$
\eatline
\label{th:acoker}
\end{theorem}

\thm{th:acoker} extends the result that the number of
domino tilings of an Aztec diamond of order $n$ is $2^{n(n+1)/2}$
\cite{MRR:asm,Kuperberg:eklp1,Kuperberg:eklp2}.

\begin{proof}

We give two arguments, one using Kasteleyn-Percus matrices and the other using
Gessel-Viennot matrices.  First, define a binomial coefficient matrix $B(n)$
by
$$B(n)_{0\leq i,j < n} = \binom{i}{j}.$$
(We will assume that rows and columns of other matrices are numbered from 0 as
well.) Define an $n\times n+1$ matrix $L(n)$ by putting the $n\times n$ identity
matrix to the left of a null column, and define $R(n)$ by putting the $n\times
n$ identity matrix to the right of a null column.  For example here are $B(4)$,
$L(3)$, and $R(3)$:
$$\begin{pmatrix}1 & 0 & 0 & 0\\1 & 1 & 0 & 0\\1 & 2 & 1 & 0\\1 & 3 & 3 & 1
\end{pmatrix} \quad
\begin{pmatrix}1 & 0 & 0 & 0\\0 & 1 & 0 & 0\\0 & 0 & 1 & 0 \end{pmatrix} \quad
\begin{pmatrix}0 & 1 & 0 & 0\\0 & 0 & 1 & 0\\0 & 0 & 0 & 1 \end{pmatrix}. $$

One can check that the matrix
\begin{align*}
M_A(n) =&\ R(n) \tensor R(n)^T + L(n) \tensor R(n)^T \\
&\ + R(n) \tensor L(n)^T - L(n) \tensor L(n)^T
\end{align*}
is a Kasteleyn-Percus matrix for the graph $Z_A(n)$.  At the same time,
$$B(n)L(n)B(n+1)^{-1} = L(n)$$
and
$$B(n)R(n)B(n+1)^{-1} = R(n)-L(n).$$
It follows that
\begin{align*}
M'(n) &\stackrel{\mathrm{def}}{=}
    (B(n) \tensor B(n+1)^{-T})M(n)(B(n+1)^{-1} \tensor B(n)^T) \\
    &= R(n) \tensor R(n)^T - 2L(n)\tensor L(n)^T.
\end{align*}
Since $B(n)$ is a triangular matrix, $M'(n)$ is equivalent to $M(n)$.  On
the other hand, one can check that, modulo permuting rows and columns,
\begin{align*}
M'(n) = &\ X(1)\oplus X(2)\oplus \dots \oplus X(n) \\
    &\ \oplus Y(1) \oplus Y(2) \oplus \dots \oplus Y(n),
\end{align*}
where
$$X(k)=\begin{pmatrix}1&-2&0&&0\\0&1&-2&\cdots&0\\0&0&1&&0\\&
\vdots&&\ddots&\vdots\\0&0&0&\cdots&1\end{pmatrix}$$
and
$$Y(k)=\begin{pmatrix}-2&1&0&&0\\0&-2&1&\cdots&0\\0&0&-2&&0\\&
\vdots&&\ddots&\vdots\\0&0&0&\cdots&-2\end{pmatrix}.$$
Since
$$\coker X(k)=0 \qquad \coker Y(k) =\Z/2^k,$$
the theorem follows.

\begin{fullfigure}{f:delannoy}{Gessel-Viennot model of an Aztec diamond.
(Not all orientations are shown.)}
\pspicture(-3,-2.8)(3,2.8)
\pcline(0,2.1)(-1,1.4)\mto\pcline(0,2.1)(1,1.4)\mto
\pcline(-1,1.4)(0,0.7)\mto\pcline( 1,1.4)(0,0.7)\mto
\pcline(0,2.1)(0,0.7)\mto
\psline(0,2.1)(0,-2.1)(3,0)(0,2.1)(-3,0)(0,-2.1)
\pspolygon(-2,-0.7)(-2,0.7)(1,-1.4)(1,1.4)
\pspolygon(-1,-1.4)(-1,1.4)(2,-0.7)(2,0.7)
\multips(-3,0)(1,-0.7){4}{\pscircle[fillstyle=solid](0,0){.2}}
\multips(-3,0)(1,0.7){4}{\pscircle[fillstyle=solid](0,0){.2}\qdisk(0,0){.1}}
\multips(-2,-0.7)(1,0.7){4}{\qdisk(0,0){.1}}
\multips(-1,-1.4)(1,0.7){4}{\qdisk(0,0){.1}}
\multips(0,-2.1)(1,0.7){4}{\qdisk(0,0){.1}}
\rput[rb](-3.2,.3){$0$}\rput[rb](-2.2,1){$1$}
\rput[rb](-1.2,1.7){$2$}\rput[rb](-0.2,2.4){$3$}
\rput[rt](-3.2,-.3){$0$}\rput[rt](-2.2,-1){$1$}
\rput[rt](-1.2,-1.7){$2$}\rput[rt](-0.2,-2.4){$3$}
\endpspicture\eatline
\end{fullfigure}

In the Gessel-Viennot approach we first observe that if $G(n)$ is a graph of
the type in \fig{f:delannoy} then its transit-free resolution $G'(n)$ as
described in \thm{th:gv} is the Aztec diamond graph $Z_A(n)$.  (The left and
right endpoints of $G(n)$ are numbered in the figure, with the left endpoints
on top.  The first left and right endpoints coincide, which is degenerate but
allowed.)  Let $V(n)$ be the Gessel-Viennot matrix of $G(n)$.  The entry
$V(n)_{i,j}$ is the Delannoy number $D(i,j)$ \cite[\S6.3]{Stanley:enumerative2}
(see also Sachs and Zernitz \cite{SZ:dimer}), because $G(n)$ matches the
defining recurrence
\begin{align*}
D(i,j) = D(i,j-1) + D(i-1,j) + D(i-1,j-1) \\
D(0,i) = D(i,0) = 1.
\end{align*}
A standard formula for Delannoy numbers is
$$D(i,j)=\sum_k\binom{i}{k}\binom{j}{k}2^k.$$
In matrix form this identity can be expressed
$$V(n)=B(n)V'(n)B(n)^T,$$
where $V'(n)$ is the Smith normal form of $V(n)$ with
$$V'(n)_{k,k}=2^k.$$
Thus the Smith normal form of $V(n)$ also establishes the theorem.
\end{proof}

Finally, we could at least conjecturally extend \thm{th:acoker} with the same
variations as those we considered for lozenge tilings:  Domino tilings with
symmetry, $q$-enumerations, impossible enumerations, Aztec diamonds with teeth
missing, etc.  For example, Tokuyama \cite{Tokuyama:gelfand}
established a relation between generating functions of lozenge-type and
Aztec-type Gelfand triangles.  We conjecture that this identity can be
extended to an equivalence of Kasteleyn-Percus (or Gessel-Viennot) matrices.
We leave this and other possibilities to future work.

\section{Appendix: Smith normal form}
\label{s:smith}

\begin{theorem} If $M$ is a $k \times n$ matrix over a principal ideal domain
$R$, then there exist invertible matrices $A$ and $B$ such that
$$\Sm(M) = AMB$$
is diagonal and $\Sm(M)_{i,i}$ divides $\Sm(M)_{i+1,i+1}$.  The matrix
$\Sm(M)$ is a \emph{Smith normal form} of $M$.
\label{th:smith}
\end{theorem}

Evidently
\begin{align*}
\coker M &\cong \coker \Sm(M) \\
    &= R^{k-n} \oplus R/\Sm(M)_{1,1} \oplus \dots \oplus R/\Sm(M)_{n,n}
\end{align*}
if $k \ge n$ and
\begin{align*}
\coker M &\cong \coker \Sm(M) \\
    &= R/\Sm(M)_{1,1} \oplus \dots \oplus R/\Sm(M)_{k,k}
\end{align*}
otherwise.  (If $R = \Z$ and we allow $n$, but not $k$, to be infinite, then
\thm{th:smith} is equivalent to the classification of finitely generated
abelian groups.)  It is easy to show that this decomposition of $\coker M$ is
unique and that $\Sm(M)$ is unique up to multiplying the entries by units.

\begin{proof}
We argue by induction on $n$ or $k$. Since $R$ is a PID, any two elements $a$
and $b$ have a greatest common divisor
$$\gcd(a,b) = ax+by$$
which is unique up to a unit factor.  Moreover, $R$ is Noetherian, which means
that any chain of divisibilities $a_{i+1}|a_i$ must eventually be constant up
to unit factors.  Thus we can argue by induction with respect to divisibility
of non-zero elements of $R$.   Since we can replace $M$ by any equivalent form,
we assume that the entry $M_{1,1} = a$ is not divisible by any entry in any
form of $M$, except for those that are $a$ times a unit.  We claim that $a$
divides every entry of $M$.  Otherwise there is an entry $M_{i,j} = b$ such
that $a \nmid b$ and $b \nmid a$.  If $b$ is in the first row or column, then
after permuting rows and columns and possibly transposing $M$, $M_{1,2} = b$:
$$M = \left(\begin{array}{cc|c}
    a & b & \cdots \\ \hline \multicolumn{2}{c|}{\vdots} & \ddots
\end{array}\right).$$
Let $c = ax+by$ be a greatest common divisor of $a$ and $b$. If we
post-multiply $M$ by the matrix
$$B = \left(\begin{array}{c|c}
    \begin{matrix}x & a/c \\ y & -b/c \end{matrix} & \mbox{\Large $0$}
    \\ \hline \mbox{\Large \rule{0ex}{2ex} $0$} & \mbox{\Large $I$}
\end{array}\right),$$
the result is a form of $M$ with the entry $c$, which contradicts the choice of
$a$.  If $a$ divides every entry in the first row and column but not some entry
$b$ elsewhere, then we first pivot at the position $(1,1)$ to obtain:
$$M = \left(\begin{array}{cc|c}
    a & 0 & \ldots \\ 0 & b & \\ \hline \multicolumn{2}{c|}{\vdots} & \ddots
\end{array}\right).$$
If we pre-multiply by
$$A = \left(\begin{array}{c|c}
    \begin{matrix}1 & 1 \\ 0 & 1 \end{matrix} & \mbox{\Large $0$}
    \\ \hline \mbox{\Large \rule{0ex}{2ex} $0$} & \mbox{\Large $I$}
\end{array}\right)$$
and post-multiply by $B$ above,
we again produce the entry $c$.

Given that $M_{1,1} = a$ does divide the rest of $M$ we perform
a deleted pivot at $(1,1)$ and assume normal form for the remaining
submatrix by induction.
\end{proof}

\begin{theorem} If $A$ is an alternating $n \times n$ matrix over a principal
ideal domain $R$, then there exists an invertible matrix $B$ such that
$$\Sm_a(A) = B^TAB$$
is block-diagonal with $2 \times 2$ blocks, and such that $\Sm_a(A)_{2i,2i+1}$
divides $\Sm_a(A)_{2i+2,2i+3}$.  The matrix $\Sm_a(A)$ is the
\emph{alternating Smith normal form} of $A$.
\label{th:asmith}
\end{theorem}
\begin{proof} The argument is the same as the one for Theorem~\ref{th:smith}.
We assume that $A_{1,2} = a$ is minimal among all entries of all forms of $A$.
If it does not divide some entry in the first two rows and columns, then
after permuting rows and columns, that entry is $A_{1,3} = b$:
$$A = \left(\begin{array}{ccc|c}
    0 & a & b &  \\ -a & 0 & \cdot & \cdots \\
    -b & \cdot & 0 & \\ \hline & \vdots & & \ddots
\end{array}\right).$$
Let $c = ax+by$ be a common divisor and let
$$B = \left(\begin{array}{c|c}
    \begin{matrix}1 & 0 & 0  \\ 0 & x & a/c \\ 0 & y & -b/c \end{matrix}
    & \mbox{\Large $0$} \\ \hline \mbox{\Large \rule{0ex}{2ex} $0$}
    & \mbox{\Large $I$}
\end{array}\right).$$
Then $B^TAB$ has the entry $c$, a contradiction.  If $a$ divides every entry in
the first two rows and columns but not some other entry $b$, then we can
perform a symmetric pivot at $(1,2)$.  After permuting rows and columns $A$
then has the form:
$$A' = \left(\begin{array}{cccc|c}
      0 & a &  0 & 0 & \\
     -a & 0 &  0 & 0 & \ldots \\
      0 & 0 &  0 & b & \\
      0 & 0 & -b & 0 & \\ \hline
      \multicolumn{4}{c|}{\vdots} & \ddots
\end{array}\right).$$
Let $c = ax+by$ be a common divisor and let
$$B = \left(\begin{array}{c|c}
    \begin{matrix}
    1 & 0 & 0 & 0 \\
    0 & 1 & 0 & 0 \\
    1 & 0 & 1 & 0 \\
    0 & 0 & 0 & 1 \end{matrix}
    & \mbox{\Large $0$} \\ \hline \mbox{\Large \rule{0ex}{2ex} $0$}
    & \mbox{\Large $I$}
\end{array}\right).$$
Then $B^TAB$ has the form of the previous case.

Finally if $a$ divides every entry of $A$, we perform a deleted symmetric pivot
at $(1,2)$ and inductively assume the normal form for the remaining submatrix.
\end{proof}

% \bibliography{me,co,qp,books}

\providecommand{\bysame}{\leavevmode\hbox to3em{\hrulefill}\thinspace}
\begin{thebibliography}{10}

\bibitem{Andrews:tsscpp}
George~E. Andrews, \emph{Plane partitions {V}: {The T. S. S. C. P. P.}
  conjecture}, J. Combin. Theory Ser. A \textbf{66} (1994), no.~1, 28--39.

\bibitem{Biggs:algebraic}
Norman Biggs, \emph{Algebraic potential theory on graphs}, Bull. London Math.
  Soc. \textbf{29} (1997), no.~6, 641--682.

\bibitem{CEKZ:triangular}
Mihai Ciucu, Theresia Eisenk\"olbl, Christian Krattenthaler, and Douglas Zare,
  \emph{Enumeration of lozenge tilings of hexagons with a central triangular
  hole}, \mbox{arXiv:math.CO/9912053}.

\bibitem{CK:centered}
Mihai Ciucu and Christian Krattenthaler, \emph{The number of centered lozenge
  tilings of a symmetric hexagon}, J. Combin. Theory Ser. A \textbf{86} (1999),
  no.~1, 103--126, \mbox{arXiv:math.CO/9712209}.

\bibitem{Kuperberg:eklp1}
Noam Elkies, Greg Kuperberg, Michael Larsen, and James Propp,
  \emph{Alternating-sign matrices and domino tilings, {I}}, J. Algebraic
  Combin. \textbf{1} (1992), no.~2, 111--132.

\bibitem{Kuperberg:eklp2}
\bysame, \emph{Alternating-sign matrices and domino tilings, {II}}, J.
  Algebraic Combin. \textbf{1} (1992), no.~3, 219--234.

\bibitem{Fisher:planar}
Michael~E. Fisher, \emph{On the dimer solution of planar {Ising} models}, J.
  Math. Phys. \textbf{7} (1966), 1776--1781.

\bibitem{GV:partitions}
Ira Gessel and Xavier~G. Viennot, \emph{Determinants, paths, and plane
  partitions}, 1989, Preprint.

\bibitem{GV:binomial}
Ira~M. Gessel and Xavier~G. Viennot, \emph{Binomial determinants, paths, and
  hook length formulas}, Adv. Math. \textbf{58} (1985), no.~3, 300--321.

\bibitem{Jockusch:perfect}
William Jockusch, \emph{Perfect matchings and perfect squares}, J. Combin.
  Theory Ser. A \textbf{67} (1994), 100--115.

\bibitem{Kasteleyn:crystal}
P.~W. Kasteleyn, \emph{Graph theory and crystal physics}, Graph theory and
  theoretical physics (F.~Harary, ed.), Academic Press, 1967.

\bibitem{Kenyon:local}
Richard Kenyon, \emph{Local statistics of lattice dimers}, Ann. Inst. H.
  Poincar\'e Probab. Statist. \textbf{33} (1997), 591--618,
  \mbox{arXiv:math.CO/0105054}.

\bibitem{KPW:trees}
Richard Kenyon, James Propp, and David Wilson, \emph{Trees and matchings},
  Electron. J. Combin. \textbf{7} (2000), \#R25, \mbox{arXiv:math.CO/9903025}.

\bibitem{Krattenthaler:advanced}
Christian Krattenthaler, \emph{Advanced determinant calculus}, S\'eminaire
  Lotharingien Combin. \textbf{42} (1999), B42q, \mbox{arXiv:math.CO/9902004}.

\bibitem{Kuperberg:perdet}
Greg Kuperberg, \emph{Symmetries of plane partitions and the
  permanent-determinant method}, J. Combin. Theory Ser. A \textbf{68} (1994),
  no.~1, 115--151.

\bibitem{Kuperberg:fun}
\bysame, \emph{An exploration of the permanent-determinant method}, Electron.
  J. Combin. \textbf{5} (1998), no.~\#R46, 16pp, \mbox{arXiv:math.CO/9810091}.

\bibitem{Lindstrom:vector}
B.~Lindstr\"om, \emph{On the vector representations of induced matroids}, Bull.
  London Math. Soc. \textbf{5} (1973), 85--90.

\bibitem{Lorenzini:attached}
Dino~J. Lorenzini, \emph{A finite group attached to the {Laplacian} of a
  graph}, Discrete Math. \textbf{91} (1991), no.~3, 277--282.

\bibitem{Merris:unimodular}
Russell Merris, \emph{Unimodular equivalence of graphs}, Linear Algebra Appl.
  \textbf{173} (1992), 181--189.

\bibitem{MRR:asm}
William~H. Mills, David~P. Robbins, and Howard Rumsey, \emph{Alternating-sign
  matrices and descending plane partitions}, J. Combin. Theory Ser. A
  \textbf{34} (1983), no.~3, 340--359.

\bibitem{Percus:dimer}
Jerome~K. Percus, \emph{One more technique for the dimer problem}, J. Math.
  Phys. \textbf{10} (1969), 1881--1888.

\bibitem{Propp:progress}
James Propp, \emph{Enumeration of matchings: problems and progress}, New
  perspectives in algebraic combinatorics ({Berkeley, CA}, 1996--97), Cambridge
  Univ. Press, Cambridge, 1999, \mbox{arXiv:math.CO/9904150}, pp.~255--291.

\bibitem{Rudin:fourier}
Walter Rudin, \emph{Fourier analysis on groups}, Wiley Interscience, 1962.

\bibitem{SZ:dimer}
Horst Sachs and Holger Zernitz, \emph{Remark on the dimer problem}, Discrete
  Appl. Math. \textbf{51} (1994), no.~1-2, 171--179.

\bibitem{Saldanha:singular}
Nicolau~C. Saldanha, \emph{Singular polynomials of generalized {Kasteleyn}
  matrices}, \mbox{arXiv:math.CO/0101002}.

\bibitem{Stanley:symmetries}
Richard~P. Stanley, \emph{Symmetries of plane partitions}, J. Combin. Theory
  Ser. A \textbf{43} (1986), no.~1, 103--113.

\bibitem{Stanley:enumerative2}
\bysame, \emph{Enumerative combinatorics}, vol.~2, Cambridge University Press,
  Cambridge, England, 1999.

\bibitem{Steane:review}
Andrew Steane, \emph{Quantum computing}, Rep. Progr. Phys. \textbf{61} (1998),
  no.~2, 117--173, \mbox{arXiv:quant-ph/9708022}.

\bibitem{Stembridge:paths}
John~R. Stembridge, \emph{Non-intersecting paths, {Pfaffians}, and plane
  partitions}, Adv. Math. \textbf{83} (1990), no.~1, 96--131.

\bibitem{Stembridge:q-1}
\bysame, \emph{Some hidden relations involving the ten symmetry classes of
  plane partitions}, J. Combin. Theory Ser. A \textbf{68} (1994), 372--409.

\bibitem{Stembridge:enumeration}
\bysame, \emph{The enumeration of totally symmetric plane partitions}, Adv.
  Math. \textbf{111} (1995), no.~2, 227--243.

\bibitem{Tokuyama:gelfand}
Takeshi Tokuyama, \emph{A generating function of strict {Gel'fand} patterns and
  some formulas on characters of general linear groups}, J. Math. Soc. Japan
  \textbf{40} (1988), 671--685.

\bibitem{Waerden:reichweite}
B.~L. van~der Waerden, \emph{Die lange {Reichweite} der regelmaessigen
  {Atomanordnung} in {Mischkristallen}}, Zeitschrift {f\"ur} Physik
  \textbf{118} (1941), 473--488.

\bibitem{Yang:thesis}
Bo-Yin Yang, \emph{Two enumeration problems about the {Aztec} diamonds}, Ph.D.
  thesis, Massachusetts Institute of Technology, 1991.

\end{thebibliography}

\end{document}

pst-node.tex
%% BEGIN pst-node.tex
%%
%% Nodes with PSTricks 97.
%% See the betadoc documentation for usage. 
%% This uses the header file `pst-node.pro'.
%%
\def\fileversion{97 patch 9}
\def\filedate{1999/04/14}
%%
%% COPYRIGHT 1993, 1994, 1999 by Timothy Van Zandt, tvz@nwu.edu.
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN
%% archives in directory macros/latex/base/lppl.txt.
%%
\message{ v\fileversion, \filedate}
\csname PSTnodesLoaded\endcsname
\let\PSTnodesLoaded\endinput
\ifx\PSTricksLoaded\endinput\else\input pstricks.tex\fi\relax
\edef\TheAtCode{\the\catcode`\@}
\catcode`\@=11
\pstheader{pst-node.pro}
\def\pst@nodedict{tx@NodeDict begin }
\def\pst@zapspace#1 #2{%
#1%
\ifx#2\@empty\else\expandafter\pst@zapspace\fi
#2}
\def\pst@getnode#1#2{%
\pst@expandafter\pst@@getnode{#1},,\@nil#2}
\def\pst@@getnode#1,#2,#3\@nil#4{%
\ifx\@empty#3\@empty
\edef#4{/N@\pst@zapspace#1 \@empty\space}%
\else
\pst@cntg=#1\relax
\pst@cnth=#2\relax
\edef#4{/N@M-\ifnum\psmatrixcnt=\z@ 1\else\the\psmatrixcnt\fi
-\the\pst@cntg-\the\pst@cnth\space}%
\fi}
\def\tx@NewNode{NewNode }
\def\pst@newnode#1#2#3#4{%
\leavevmode
\pst@getnode{#1}\pst@thenode
\pst@Verb{%
\pst@nodedict
{#3}
\ifx\psk@name\relax false \else \psk@name true \fi
\pst@thenode
#2
{#4}
\tx@NewNode
end}%
\global\let\psk@name\relax
\pstree@nodehook
\global\let\pstree@nodehook\relax}
\let\pstree@nodehook\relax
\newif\ifnodealign
\def\psset@nodealign#1{\@nameuse{nodealign#1}}
\psset@nodealign{false}
\def\pst@nodealign{%
\pst@dimg=\ht\pst@hbox
\advance\pst@dimg-\dp\pst@hbox
\divide\pst@dimg2
\lower\pst@dimg}
\def\tx@InitPnode{InitPnode }
\def\pnode{\@ifnextchar({\pnode@}{\pnode@(0,0)}}
\def\pnode@(#1)#2{%
\pst@@getcoor{#1}%
\pst@newnode{#2}{10}{\pst@coor}{\tx@InitPnode}%
\ignorespaces}
\def\tx@InitCnode{InitCnode }
\def\cnode{\pst@object{cnode}}
\def\cnode@i{\@ifnextchar({\cnode@ii}{\cnode@ii(0,0)}}
\def\cnode@ii(#1)#2#3{%
\leavevmode
\hbox{%
\use@par
\pst@@getcoor{#1}%
\pssetlength\pst@dimc{#2}%
\pst@dimg=\psk@dimen\pslinewidth
\advance\pst@dimc-\pst@dimg
\advance\pst@dimc.5\pslinewidth
\ifnodealign
\kern\pst@dimc
\vrule width\z@ height \pst@dimc depth \pst@dimc
\fi
\pscircle@do(#1){#2}%
\pst@newnode{#3}{11}{\pst@coor \pst@number\pst@dimc}{\tx@InitCnode}%
% DG/SR modification begin - Jul. 30, 1997 - Patch 2
%\ifnodealign \kern\pst@dimc\egroup \fi}%
\ifnodealign\kern\pst@dimc\fi}%
% DG/SR modification end
\ignorespaces}
\def\Cnode{\pst@object{Cnode}}
\def\Cnode@i{\@ifnextchar({\Cnode@ii}{\Cnode@ii(0,0)}}
\def\Cnode@ii(#1)#2{\cnode@ii(#1){\psk@radius}{#2}}%
\def\cnodeput{\pst@object{cnodeput}}
\def\cnodeput@i{\@ifnextchar({\cnodeput@iii}{\cnodeput@ii}}
\def\cnodeput@ii#1{%
\addto@par{rot={#1}}%
\@ifnextchar({\cnodeput@iii}{\cnodeput@iii(\z@,\z@)}}
\def\cnodeput@iii(#1)#2{%
\pst@killglue
\@fixedradiusfalse
\def\pst@nodehook{\cnodeput@iv{#2}}%
\pst@makebox{\cput@v{#1}}}
\def\cnodeput@iv#1{%
\pst@newnode{#1}{11}{\pscirclebox@iv \pst@number\pslinewidth add}%
{\tx@InitCnode}%
\global\let\pst@nodehook\relax}
\def\Cnodeput{\pst@object{Cnodeput}}
\def\Cnodeput@i{\@ifnextchar({\Cnodeput@iii}{\Cnodeput@ii}}
\def\Cnodeput@ii#1{%
\addto@par{rot={#1}}%
\@ifnextchar({\Cnodeput@iii}{\Cnodeput@iii(\z@,\z@)}}
\def\Cnodeput@iii(#1)#2{%
\pst@killglue
\@fixedradiustrue
\def\pst@nodehook{\Cnodeput@iv{#2}}%
\pst@makebox{\cput@iv{#1}}}
\def\Cnodeput@iv#1{%
\pst@newnode{#1}{11}{%
\pst@number{\wd\pst@hbox} 2 div \pst@number\pst@dima % x y
\pst@number\pst@dimb \pst@number\pslinewidth \psk@dimen .5 sub mul sub }% r
{\tx@InitCnode}%
\global\let\pst@nodehook\relax}
\def\circlenode{\pst@object{circlenode}}
\def\circlenode@i#1{\pst@makebox{\circlenode@ii{#1}}}
\def\circlenode@ii#1{%
\begingroup
\pst@useboxpar
\setbox\pst@hbox=\hbox{%
\cnodeput@iv{#1}%
\pscirclebox@iii
\box\pst@hbox}%
\ifnodealign \psboxseptrue \fi
\ifpsboxsep \pscirclebox@sep \fi
\leavevmode
\ifnodealign\pst@nodealign\fi
\box\pst@hbox
\endgroup}
\def\Circlenode{\pst@object{Circlenode}}
\def\Circlenode@i#1{\pst@makebox{\Circlenode@ii{#1}}}
\def\Circlenode@ii#1{%
\begingroup
\pst@useboxpar
\pst@dima=\ht\pst@hbox
\advance\pst@dima\dp\pst@hbox
\divide\pst@dima\tw@
\pssetlength\pst@dimb\psk@radius
\setbox\pst@hbox=\hbox{%
\Cnodeput@iv{#1}%
\pscircle(.5\wd\pst@hbox,\pst@dima){\pst@dimb}%
\box\pst@hbox}%
\ifnodealign \psboxseptrue \fi
\ifpsboxsep \psCirclebox@sep \fi
\leavevmode
\ifnodealign\pst@nodealign\fi
\box\pst@hbox
\endgroup}
\def\tx@GetRnodePos{GetRnodePos }
\def\tx@InitRnode{InitRnode }
\def\rnode{\@ifnextchar[{\rnode@i}{\def\pst@par{}\rnode@ii}}
\def\rnode@i[#1]{\def\pst@par{ref=#1}\rnode@ii}
\def\rnode@ii#1{\pst@makebox{\rnode@iii\rnode@iv{#1}}}
\def\rnode@iii#1#2{%
% DG modification begin - Jan. 1997
\leavevmode
% DG modification end
\begingroup
% DG/SR modification begin - Apr. 28, 1998 - Patch 6
\pst@useboxpar
% DG/SR modification end
#1%
\if@star\pst@starbox\fi
\ifnodealign\lower\pst@dimb\fi
\hbox{%
\pst@newnode{#2}{16}{%
\pst@number{\ht\pst@hbox}%
\pst@number{\dp\pst@hbox}%
\pst@number{\wd\pst@hbox}%
\pst@number\pst@dima
\pst@number\pst@dimb}%
{\tx@InitRnode}%
\box\pst@hbox}%
\endgroup}
\def\rnode@iv{%
\pst@dima=\psk@xref\wd\pst@hbox
\ifx\psk@yref\relax
\pst@dimb=\z@
\else
\pst@dimb=\ht\pst@hbox
\advance\pst@dimb\dp\pst@hbox
\pst@dimb=\psk@yref\pst@dimb
\advance\pst@dimb-\dp\pst@hbox
\fi}
\def\psset@href#1{\pst@checknum{#1}\psk@href}
\psset@href{0}
\def\psset@vref#1{\def\psk@vref{#1}}
\psset@vref{.7ex}
\def\Rnode{\pst@object{Rnode}}
\def\Rnode@i#1{\pst@makebox{\rnode@iii\Rnode@ii{#1}}}
\def\Rnode@ii{%
% DG modification begin - Jan. 1997
%   - \begingroup removed  as it seems to doesn't work any more
%   - \Rnode doesn't process the optional parameter changes
%\begingroup
\use@par
% DG modification end
\pst@dima=\psk@href\wd\pst@hbox
\advance\pst@dima\wd\pst@hbox
\divide\pst@dima 2
\pssetlength\pst@dimb{\psk@vref}}
\def\tx@DiaNodePos{DiaNodePos }
\def\dianode{\pst@object{dianode}}
\def\dianode@i#1{\pst@makebox{\dianode@ii{#1}}}
\def\dianode@ii#1{%
\begingroup
\pst@useboxpar
\psdiabox@iii
\setbox\pst@hbox=\hbox{%
\pst@newnode{#1}{14}{}{%
/X \pst@number\pst@dima def
/Y \pst@number\pst@dimb def
/w \pst@number\pst@dimc 2 mul def
/h \pst@number\pst@dimd 2 mul def
/NodePos { \tx@DiaNodePos } def}%
\box\pst@hbox}%
\ifnodealign\psboxseptrue\fi
\ifpsboxsep\psdiabox@sep\fi
% DG/SR modification begin - Sep. 2, 1997 - Patch 3
\leavevmode
% DG/SR modification end
\ifnodealign\lower\pst@dimb\fi
\box\pst@hbox
\endgroup}
\def\tx@TriNodePos{TriNodePos }
\def\tx@InitTriNode{InitTriNode }
\def\trinode{\pst@object{trinode}}
\def\trinode@i#1{\pst@makebox{\trinode@ii{#1}}}
\def\trinode@ii#1{%
\begingroup
\pst@useboxpar
\pstribox@iii
\setbox\pst@hbox=\hbox{%
\pst@newnode{#1}{14}{}{%
\pst@number\pst@dimc
\pst@number\pst@dimd
\ifodd\psk@trimode
exch
\pst@number\pst@dima
\else
\pst@number\pst@dimb
\fi
\psk@trimode
\pst@number{\wd\pst@hbox}%
\pst@number{\ht\pst@hbox}%
\pst@number{\dp\pst@hbox}%
\tx@InitTriNode}%
\box\pst@hbox}%
\ifnodealign\psboxseptrue\fi
\ifpsboxsep\pstribox@sep\fi
% DG/SR modification begin - Sep. 2, 1997 - Patch 3
\leavevmode
% DG/SR modification end
\ifnodealign\lower\pst@tempa\fi
\box\pst@hbox
\endgroup}
\def\tx@OvalNodePos{OvalNodePos }
\def\ovalnode{\pst@object{ovalnode}}
\def\ovalnode@i#1{\pst@makebox{\ovalnode@ii{#1}}}
\def\ovalnode@ii#1{%
\begingroup
\pst@useboxpar
\psovalbox@iii
\setbox\pst@hbox=\hbox{%
\pst@newnode{#1}{14}{}{%
/X \pst@number\pst@dima def
/Y \pst@number\pst@dimb def
/w \pst@number\pst@dimc def
/h \pst@number\pst@dimd def
/NodePos { \tx@OvalNodePos } def}%
\unhbox\pst@hbox}%
\ifnodealign\psboxseptrue\fi
\ifpsboxsep\psovalbox@sep\fi
% DG/SR modification begin - Sep. 2, 1997 - Patch 3
\leavevmode
% DG/SR modification end
\ifnodealign\lower\pst@dimb\fi
\box\pst@hbox
\endgroup}
\def\dotnode{\pst@object{dotnode}}
\def\dotnode@i{\@ifnextchar({\dotnode@ii}{\dotnode@ii(\z@,\z@)}}
\def\dotnode@ii(#1)#2{%
\leavevmode
\hbox{%
\use@par
\pst@@getcoor{#1}%
\pst@getdotsize
\pstree@nodehook
\ifnodealign
\pst@dima=\pst@dimg
\kern\pst@dima
\vrule width\z@ height \pst@dimh depth \pst@dimh
\fi
\pst@newnode{#2}{14}{}{%
\pst@coor
/Y ED /X ED
/w \pst@number\pst@dimg def
/h \pst@number\pst@dimh def
/NodePos { \tx@OvalNodePos } def}%
\psdot@ii(#1)%
\ifnodealign\kern\pst@dima\fi}%
\ignorespaces}
\def\psset@framesize#1{\pst@expandafter\psset@@framesize{#1} \@nil}
\def\psset@@framesize#1 #2\@nil{%
\pssetlength\pst@dimg{#1}%
\divide\pst@dimg2
\edef\psk@framewidth{\pst@number\pst@dimg}%
\ifx\@empty#2\@empty
\let\psk@frameheight\psk@framewidth
\else
\pssetlength\pst@dimg{#2}%
\divide\pst@dimg2
\edef\psk@frameheight{\pst@number\pst@dimg}%
\fi}
\psset@framesize{10pt}
\def\fnode{\pst@object{fnode}}
\def\fnode@i{\@ifnextchar({\fnode@ii}{\fnode@ii(\z@,\z@)}}
\def\fnode@ii(#1)#2{%
\leavevmode
\pst@killglue
\hbox{%
\use@par
\begin@ClosedObj
\ifnodealign
\kern\psk@framewidth\p@
\vrule width\z@ height \psk@frameheight\p@ depth \psk@frameheight\p@
\edef\pst@coor{0 0 }%
\else
\pst@@getcoor{#1}%
\fi
\pst@newnode{#2}{14}{}{%
\pst@coor
/Y ED /X ED
/d \psk@dimen .5 sub CLW mul neg def
/r \psk@framewidth d add def
/l r neg def
/u \psk@frameheight d add def
/d u neg def
/NodePos { \tx@GetRnodePos } def}%
\addto@pscode{%
/x2 \psk@framewidth CLW \psk@dimen mul sub def
/y2 \psk@frameheight CLW \psk@dimen mul sub def
\pst@coor 2 copy
y2 sub /y1 ED
x2 sub /x1 ED
y2 add /y2 ED
x2 add /x2 ED
\psk@cornersize
1 index 0 eq { pop pop \tx@Rect } { \tx@OvalFrame } ifelse}%
\def\pst@linetype{2}%
\showpointsfalse
\end@ClosedObj
\ifnodealign\kern\psk@framewidth\p@\fi}%
\ignorespaces}
\def\psset@nodesepA#1{%
\pst@getlength{#1}\psk@nodesepA
\def\psk@nodeseptypeA{0 }}
\def\psset@nodesepB#1{%
\pst@getlength{#1}\psk@nodesepB
\def\psk@nodeseptypeB{0 }}
\def\psset@nodesep#1{%
\pst@getlength{#1}\psk@nodesepA
\let\psk@nodesepB\psk@nodesepA
\def\psk@nodeseptypeA{0 }%
\def\psk@nodeseptypeB{0 }}
\psset@nodesep{0pt}
\def\psset@XnodesepA#1{%
\pst@getlength{#1}\psk@nodesepA
\def\psk@nodeseptypeA{1 }}
\def\psset@XnodesepB#1{%
\pst@getlength{#1}\psk@nodesepB
\def\psk@nodeseptypeB{1 }}
\def\psset@Xnodesep#1{%
\pst@getlength{#1}\psk@nodesepA
\let\psk@nodesepB\psk@nodesepA
\def\psk@nodeseptypeA{1 }%
\def\psk@nodeseptypeB{1 }}
\def\psset@YnodesepA#1{%
\pst@getlength{#1}\psk@nodesepA
\def\psk@nodeseptypeA{2 }}
\def\psset@YnodesepB#1{%
\pst@getlength{#1}\psk@nodesepB
\def\psk@nodeseptypeB{2 }}
\def\psset@Ynodesep#1{%
\pst@getlength{#1}\psk@nodesepA
\let\psk@nodesepB\psk@nodesepA
\def\psk@nodeseptypeA{2 }%
\def\psk@nodeseptypeB{2 }}
\def\psset@armA#1{%
\pst@getlength{#1}\psk@armA
\def\psk@armtypeA{0 }}
\def\psset@armB#1{%
\pst@getlength{#1}\psk@armB
\def\psk@armtypeB{0 }}
\def\psset@arm#1{%
\pst@getlength{#1}\psk@armA
\let\psk@armB\psk@armA
\def\psk@armtypeA{0 }%
\def\psk@armtypeB{0 }}
\psset@arm{10pt}
\def\psset@XarmA#1{%
\pst@getlength{#1}\psk@armA
\def\psk@armtypeA{1 }}
\def\psset@XarmB#1{%
\pst@getlength{#1}\psk@armB
\def\psk@armtypeB{1 }}
\def\psset@Xarm#1{%
\pst@getlength{#1}\psk@armA
\let\psk@armB\psk@armA
\def\psk@armtypeA{1 }%
\def\psk@armtypeB{1 }}
\def\psset@YarmA#1{%
\pst@getlength{#1}\psk@armA
\def\psk@armtypeA{2 }}
\def\psset@YarmB#1{%
\pst@getlength{#1}\psk@armB
\def\psk@armtypeB{2 }}
\def\psset@Yarm#1{%
\pst@getlength{#1}\psk@armA
\let\psk@armB\psk@armA
\def\psk@armtypeA{2 }%
\def\psk@armtypeB{2 }}
\def\psset@offsetA#1{\pst@getlength{#1}\psk@offsetA}
\def\psset@offsetB#1{\pst@getlength{#1}\psk@offsetB}
\def\psset@offset#1{\psset@offsetA{#1}\let\psk@offsetB\psk@offsetA}
\psset@offset{0pt}
\def\psset@angleA#1{\pst@getangle{#1}\psk@angleA}
\def\psset@angleB#1{\pst@getangle{#1}\psk@angleB}%
\def\psset@angle#1{%
\pst@getangle{#1}\psk@angleA
\let\psk@angleB\psk@angleA}
\psset@angle{0}
\def\psset@arcangleA#1{\pst@getangle{#1}\psk@arcangleA}
\def\psset@arcangleB#1{\pst@getangle{#1}\psk@arcangleB}%
\def\psset@arcangle#1{%
\pst@getangle{#1}\psk@arcangleA
\let\psk@arcangleB\psk@arcangleA}
\psset@arcangle{8}
\def\psset@ncurvA#1{\pst@checknum{#1}\psk@ncurvA}
\def\psset@ncurvB#1{\pst@checknum{#1}\psk@ncurvB}%
\def\psset@ncurv#1{\psset@ncurvA{#1}\let\psk@ncurvB\psk@ncurvA}
\psset@ncurv{.67}
\def\tx@GetCenter{GetCenter }
\def\tx@XYPos{XYPos }
\def\tx@GetEdge{GetEdge }
\def\tx@AddOffset{AddOffset }
\def\tx@GetEdgeA{GetEdgeA }
\def\tx@GetEdgeB{GetEdgeB }
\def\tx@GetArmA{GetArmA }
\def\tx@GetArmB{GetArmB }
\def\check@arrow#1#2{%
\check@@arrow#2-\@nil
\if@pst
\addto@par{arrows=#2}%
\def\next{#1}%
\else
\def\next{#1{#2}}%
\fi
\next}
\def\check@@arrow#1-#2\@nil{%
\ifx\@nil#2\@nil\@pstfalse\else\@psttrue\fi}
\def\tx@InitNC{InitNC }
\def\nc@object#1#2#3#4#5{%
\csname begin@#1Obj\endcsname
\showpointsfalse
\pst@getnode{#2}\pst@tempa
\pst@getnode{#3}\pst@tempb
\gdef\npos@default{#4 }%
\addto@pscode{%
/NCLW CLW def
\pst@nodedict
\psk@offsetA
\psk@offsetB neg
\psk@nodesepA
\psk@nodesepB
\psk@nodeseptypeA
\psk@nodeseptypeB
\pst@tempa
\pst@tempb
\tx@InitNC { #5 } if
end}%
\def\use@pscode{%
\pst@Verb{gsave \tx@STV newpath \pst@code\space grestore}%
\gdef\pst@code{}}%
\csname end@#1Obj\endcsname
\pst@shortput}
\def\npos@default{.5 }
\def\pc@object#1{%
\@ifnextchar({\pc@@object#1}{\pst@getarrows{\pc@@object#1}}}
\def\pc@@object#1(#2)(#3){%
\pnode(#2){@@A}\pnode(#3){@@B}%
#1{@@A}{@@B}}
\def\tx@LPutLine{LPutLine }
\def\tx@LPutLines{LPutLines }
\def\tx@BezierMidpoint{BezierMidpoint }
\def\tx@HPosBegin{HPosBegin }
\def\tx@HPosEnd{HPosEnd }
\def\tx@HPutLine{HPutLine }
\def\tx@HPutLines{HPutLines }
\def\tx@VPosBegin{VPosBegin }
\def\tx@VPosEnd{VPosEnd }
\def\tx@VPutLine{VPutLine }
\def\tx@VPutLines{VPutLines }
\def\tx@HPutCurve{HPutCurve }
\def\tx@NCCoor{NCCoor }
\def\tx@NCLine{NCLine }
\def\ncline{\pst@object{ncline}}
\def\ncline@i{\check@arrow{\ncline@ii}}
\def\ncline@ii#1#2{\nc@object{Open}{#1}{#2}{.5}{\tx@NCLine}}
\def\pcline{\pst@object{pcline}}
\def\pcline@i{\pc@object\ncline@ii}
\def\ncLine{\pst@object{ncLine}}
\def\ncLine@i{\check@arrow{\ncLine@ii}}
\def\ncLine@ii#1#2{\nc@object{Open}{#1}{#2}{.5}%
% DG/SR modification begin - Apr. 14, 1999 - Patch 9
%{\tx@NCLine /LPutPos { xB xA yB yA \tx@LPutLine } def}}
{\tx@NCLine /LPutPos { xB yB xA yA \tx@LPutLine } def}}
% DG/SR modification end
\def\tx@NCLines{NCLines }
\def\nclines{\pst@object{nclines}}
\def\nclines@i{\check@arrow\nclines@ii}
\def\nclines@ii#1#2{%
\begingroup
\use@par
\def\pst@aftercoors{\nclines@iii{#1}{#2}}%
\def\pst@coors{}%
\pst@@getcoors}
\def\nclines@iii#1#2{%
\nc@object{Open}{#1}{#2}{.5}{%
tx@Dict begin \psline@iii pop end
mark \pst@coors \tx@NCLines}%
\endgroup
\ignorespaces}
\def\tx@NCCurve{NCCurve }
\def\nccurve{\pst@object{nccurve}}
\def\nccurve@i{\check@arrow{\nccurve@ii}}
\def\nccurve@ii#1#2{\nc@object{Open}{#1}{#2}{.5}{%
/AngleA \psk@angleA\space def /AngleB \psk@angleB\space def
\psk@ncurvB\space \psk@ncurvA\space
\tx@NCCurve}}
\def\pccurve{\pst@object{pccurve}}
\def\pccurve@i{\pc@object\nccurve@ii}
\def\ncarc{\pst@object{ncarc}}
\def\ncarc@i{\check@arrow{\ncarc@ii}}
\def\ncarc@ii#1#2{\nc@object{Open}{#1}{#2}{.5}{%
yB yA sub xB xA sub \tx@Atan dup
\psk@arcangleA\space add /AngleA ED
\psk@arcangleB\space sub 180 add /AngleB ED
\psk@ncurvB\space \psk@ncurvA\space
\tx@NCCurve}}
\def\pcarc{\pst@object{pcarc}}
\def\pcarc@i{\pc@object\ncarc@ii}
\def\tx@NCAngles{NCAngles }
\def\ncangles{\pst@object{ncangles}}
\def\ncangles@i{\check@arrow{\ncangles@ii}}
\def\ncangles@ii#1#2{%
\nc@object{Open}{#1}{#2}{1.5}{\ncangles@iii \tx@NCAngles}}
\def\ncangles@iii{%
tx@Dict begin \psline@iii pop end
/AngleA \psk@angleA def
/AngleB \psk@angleB def
/ArmA \psk@armA def
/ArmB \psk@armB def
/ArmTypeA \psk@armtypeA def
/ArmTypeB \psk@armtypeB def }
\def\pcangles{\pst@object{pcangles}}
\def\pcangles@i{\pc@object\ncangles@ii}
\def\tx@NCAngle{NCAngle }
\def\ncangle{\pst@object{ncangle}}
\def\ncangle@i{\check@arrow{\ncangle@ii}}
\def\ncangle@ii#1#2{%
\nc@object{Open}{#1}{#2}{1.5}{\ncangles@iii \tx@NCAngle}}
\def\pcangle{\pst@object{pcangle}}
\def\pcangle@i{\pc@object\ncangle@ii}
\def\tx@NCBar{NCBar }
\def\ncbar{\pst@object{ncbar}}
\def\ncbar@i{\check@arrow{\ncbar@ii}}
\def\ncbar@ii#1#2{\nc@object{Open}{#1}{#2}{1.5}{%
\ncangles@iii /AngleB \psk@angleA def \tx@NCBar}}
\def\pcbar{\pst@object{pcbar}}
\def\pcbar@i{\pc@object\ncbar@ii}
\def\tx@NCDiag{NCDiag }
\def\ncdiag{\pst@object{ncdiag}}
\def\ncdiag@i{\check@arrow{\ncdiag@ii}}
\def\ncdiag@ii#1#2{%
\nc@object{Open}{#1}{#2}{1.5}{\ncangles@iii \tx@NCDiag}}
\def\pcdiag{\pst@object{pcdiag}}
\def\pcdiag@i{\pc@object\ncdiag@ii}
\def\tx@NCDiagg{NCDiagg }
\def\ncdiagg{\pst@object{ncdiagg}}
\def\ncdiagg@i{\check@arrow{\ncdiagg@ii}}
\def\ncdiagg@ii#1#2{%
\nc@object{Open}{#1}{#2}{.5}{\ncangles@iii \tx@NCDiagg}}
\def\pcdiagg{\pst@object{pcdiagg}}
\def\pcdiagg@i{\pc@object\ncdiagg@ii}
\def\tx@NCLoop{NCLoop }
\def\psset@loopsize#1{\pst@getlength{#1}\psk@loopsize}
\psset@loopsize{1cm}
\def\ncloop{\pst@object{ncloop}}
\def\ncloop@i{\check@arrow{\ncloop@ii}}
\def\ncloop@ii#1#2{%
\nc@object{Open}{#1}{#2}{2.5}%
{\ncangles@iii /loopsize \psk@loopsize def \tx@NCLoop}}
\def\pcloop{\pst@object{pcloop}}
\def\pcloop@i{\pc@object\ncloop@ii}
\def\tx@NCCircle{NCCircle }
\def\nccircle{\pst@object{nccircle}}
\def\nccircle@i{\check@arrow{\nccircle@ii}}
\def\nccircle@ii#1#2{%
\pssetlength\pst@dima{#2}%
\nc@object{Open}{#1}{#1}{.5}{%
/AngleA \psk@angleA def
/r \pst@number\pst@dima def
\tx@NCCircle \psarc@v end}}
\def\tx@NCBox{NCBox }
\def\ncbox{\pst@object{ncbox}}
\def\ncbox@i{\check@arrow{\ncbox@ii}}
\def\ncbox@ii#1#2{%
\def\pst@linetype{2}%
\nc@object{Closed}{#1}{#2}{.5}{%
tx@Dict begin \psline@iii pop end
\psk@boxheight \psk@boxdepth
\tx@NCBox}}
\def\pcbox{\pst@object{pcbox}}
\def\pcbox@i{\pc@object\ncbox@ii}
\def\tx@NCArcBox{NCArcBox }
\def\psset@boxheight#1{\pst@getlength{#1}\psk@boxheight}
\def\psset@boxdepth#1{\pst@getlength{#1}\psk@boxdepth}
\def\psset@boxsize#1{%
\psset@boxheight{#1}%
\let\psk@boxdepth\psk@boxheight}
\psset@boxsize{.4cm}
\def\ncarcbox{\pst@object{ncarcbox}}
\def\ncarcbox@i{\check@arrow{\ncarcbox@ii}}
\def\ncarcbox@ii#1#2{%
\def\pst@linetype{1}%
\nc@object{Closed}{#1}{#2}{.5}{%
\psk@arcangleA \psk@boxheight \psk@boxdepth \pst@number\pslinearc
\tx@NCArcBox}}
\def\pcarcbox{\pst@object{pcarcbox}}
\def\pcarcbox@i{\pc@object\ncarcbox@ii}
\def\tx@Tfan{Tfan }
% Changed according pst-beta.bug December 3, 1993
% nrot=:<angle> does not work when : is active.
\begingroup
\catcode`\:=13
\gdef\pst@activerot{\def:{\string:}}
\endgroup
\def\psset@nrot#1{%
\begingroup
\pst@activerot
\pst@expandafter{\@ifnextchar:{\psset@@nrot}{\psset@@rot}}{#1}\@nil
\global\let\pst@tempg\psk@rot
\endgroup
\let\psk@nrot\pst@tempg}
\def\psset@@nrot:#1\@nil{%
\psset@@rot#1\@nil
\edef\psk@rot{NAngle \ifx\psk@rot\@empty\else\psk@rot add \fi}}
\psset@nrot{0}
\def\tx@LPutCoor{LPutCoor }
\def\tx@LPut{LPut }
\def\psset@npos#1{%
\def\pst@tempa{#1}%
\ifx\pst@tempa\@empty
\def\psk@npos{\npos@default}%
\else
\pst@checknum{#1}\psk@npos
\fi}
\psset@npos{}
\def\ncput{\pst@object{ncput}}
\def\ncput@i{\pst@killglue\pst@makebox{\ncput@ii}}
\def\ncput@ii{%
\begingroup
\use@par
\if@star\pst@starbox\fi
\pst@makesmall\pst@hbox
\pst@rotate\psk@nrot\pst@hbox
\ncput@iii
\endgroup
\pst@shortput}
\def\ncput@iii{%
\leavevmode
\hbox{%
\pst@Verb{%
\pst@nodedict
/t \psk@npos def
\tx@LPut
end
\tx@PutBegin}%
\box\pst@hbox
\pst@Verb{\tx@PutEnd}}}
\def\naput{\pst@object{naput}}
\def\naput@i{\pst@killglue\pst@makebox{\naput@ii{NAngle 90 add}}}
\def\naput@ii#1{%
\begingroup
\use@par
\if@star\pst@starbox\fi
\def\psk@refangle{#1 }%
\let\psk@rot\psk@nrot
\uput@vii
{exch pop add a \tx@PtoC h1 add exch w1 add exch }%
{tx@Dict /NCLW known { NCLW add } if }%
\ncput@iii
\endgroup
\pst@shortput}
\def\nbput{\pst@object{nbput}}
\def\nbput@i{\pst@killglue\pst@makebox{\naput@ii{NAngle 90 sub}}}
\def\psset@tpos#1{%
\pst@checknum{#1}\psk@tpos
\ifdim\psk@tpos \p@<\z@
\def\psk@tpos{.5}%
% DG/SR modification begin - Sep. 23, 1998 - Patch 7
%\@pstrickserr{Bad `tpos' value: `#1'. Must be 0<tpos<1}\@epha
\@pstrickserr{Bad `tpos' value: `#1'. Must be 0<tpos<1}\@ehpa
% DG/SR modification end
\else
\ifdim\psk@tpos \p@>\p@
\def\psk@tpos{.5}%
% DG/SR modification begin - Sep. 23, 1998 - Patch 7
%\@pstrickserr{Bad `tpos' value: `#1'. Must be 0<tpos<1}\@epha
\@pstrickserr{Bad `tpos' value: `#1'. Must be 0<tpos<1}\@ehpa
% DG/SR modification end
\fi
\fi}
\psset@tpos{.5}
\def\tvput{\pst@object{tvput}}
\def\tvput@i{\pst@makebox{\psput@tput{H}{1}}}
\def\tlput{\pst@object{tlput}}
\def\tlput@i{\pst@makebox{\psput@tput{H}{true}}}
\def\trput{\pst@object{trput}}
\def\trput@i{\pst@makebox{\psput@tput{H}{false}}}
\def\thput{\pst@object{thput}}
\def\thput@i{\pst@makebox{\psput@tput{V}{1}}}
\def\taput{\pst@object{taput}}
\def\taput@i{\pst@makebox{\psput@tput{V}{true}}}
\def\tbput{\pst@object{tbput}}
\def\tbput@i{\pst@makebox{\psput@tput{V}{false}}}
\def\tx@HPutAdjust{HPutAdjust }
\def\tx@VPutAdjust{VPutAdjust }
\def\psput@tput#1#2{%
\begingroup
\use@par
\pst@tputmakesmall
\leavevmode
\hbox{%
\pst@Verb{%
\pst@nodedict
/t \psk@tpos \pst@tposflip def
tx@NodeDict /HPutPos known
{ #1PutPos }
{ CP /Y ED /X ED /NAngle 0 def /NCLW 0 def }
ifelse
/Sin NAngle sin def
/Cos NAngle cos def
/s \pst@number\pslabelsep NCLW add def
/l \pst@number\pst@dima def
/r \pst@number\pst@dimb def
/h \pst@number\pst@dimc def
/d \pst@number\pst@dimd def
% DG/SR modification begin - Sep. 26, 1997 - Patch 4
%\ifnum1=0#2\else
\ifnum1=0#2 \else
% DG/SR modification end
/flag #2 def
\csname tx@#1PutAdjust\endcsname
\fi
\tx@LPutCoor
end
\tx@PutBegin}%
\box\pst@hbox
\pst@Verb{\tx@PutEnd}}%
\endgroup
\pst@shortput}
\def\pst@tposflip{}
\def\pst@tputmakesmall{%
\pst@dima=\wd\pst@hbox
\divide\pst@dima 2
\pst@dimg=\psk@href\pst@dimg
\pst@dimb\pst@dima
\advance\pst@dima\pst@dimg % leftsize
\advance\pst@dimb-\pst@dimg % rightsize
\pst@dimd=\psk@vref\relax
\pst@dimc=\ht\pst@hbox
\advance\pst@dimc-\pst@dimd % height
\advance\pst@dimd\dp\pst@hbox % depth
\setbox\pst@hbox=\hbox to\z@{%
\kern-\pst@dima\vbox to\z@{\vss\box\pst@hbox\vskip-\pst@dimd}\hss}}
\def\MakeShortNab#1#2{%
  \def\pst@shortput@nab{%
    \def\pst@tempg{\next}%
    \ifx#1\next
      \let\pst@tempg\naput
    \else
      \ifx#2\next
        \let\pst@tempg\nbput
      \else
        \ifx\@sptoken\next
          \let\pst@tempg\pst@shortput
        \fi
      \fi
    \fi
    \pst@tempg}}
\MakeShortNab{^}{_}
\def\MakeShortTablr#1#2#3#4{%
  \def\pst@shortput@tablr{%
    \def\pst@tempg{\next}%
    \ifx#1\next
      \let\pst@tempg\taput
    \else
      \ifx#2\next
        \let\pst@tempg\tbput
      \else
        \ifx#3\next
          \let\pst@tempg\tlput
        \else
          \ifx#4\next
            \let\pst@tempg\trput
          \else
            \ifx\@sptoken\next
              \let\pst@tempg\pst@shortput
            \fi
          \fi
        \fi
      \fi
    \fi
    \pst@tempg}}
\MakeShortTablr{^}{_}{<}{>}
\def\MakeShortTab#1#2{%
  \def\pst@shortput@tab{%
    \def\pst@tempg{\next}%
    \ifx#1\next
      \def\pst@tempg{%
        \@nameuse{%
          t\ifodd\psk@treemode\ifpstreeflip b\else a\fi
          \else\ifpstreeflip r\else l\fi\fi put}}%
    \else
      \ifx#2\next
        \def\pst@tempg{%
          \@nameuse{%
            t\ifodd\psk@treemode\ifpstreeflip a\else b\fi
            \else\ifpstreeflip l\else r\fi\fi put}}%
      \else
        \ifx\@sptoken\next
          \let\pst@tempg\pst@shortput
        \fi
      \fi
    \fi
    \pst@tempg}}
\MakeShortTab{^}{_}
\def\psset@shortput#1{%
\def\pst@tempg{#1}%
\ifx\pst@tempg\@none
\let\pst@shortput\ignorespaces
\else
\@ifundefined{pst@shortput@#1}%
{\@pstrickserr{Bad short put: `#1'}\@ehpa}%
{\edef\pst@shortput{\noexpand\afterassignment\expandafter\noexpand
\csname pst@shortput@#1\endcsname\noexpand\let\noexpand\next}}%
\fi}
\psset@shortput{none}
\def\lput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\lput@i}{\lput@ii}}}
\def\lput@i[#1]{\addto@par{ref=#1}\lput@ii}
\def\lput@ii{\@ifnextchar({\lput@iv}{\lput@iii}}
\def\lput@iii#1{\addto@par{nrot=#1}\@ifnextchar({\lput@iv}{\ncput@i}}
\def\lput@iv(#1){\addto@par{npos=#1}\ncput@i}
\def\mput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\mput@i}{\ncput@i}}}
\def\mput@i[#1]{\addto@par{ref=#1}\ncput@i}
\def\Lput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\Lput@ii}{\Lput@i}}}
\def\Lput@i#1{\addto@par{labelsep=#1}\Lput@ii}
\def\Lput@ii[#1]{\addto@par{ref={#1}}\@ifnextchar({\Lput@iv}{\Lput@iii}}
\def\Lput@iii#1{\addto@par{nrot={#1}}\@ifnextchar({\Lput@iv}{\Lput@v}}
\def\Lput@iv(#1){\addto@par{npos=#1}\Lput@v}
\def\Lput@v{\pst@killglue\pst@makebox{\Lput@vi}}
\def\Lput@vi{%
\begingroup
\use@par
\if@star\pst@starbox\fi
\Rput@vi
\pst@makesmall\pst@hbox
\pst@rotate\psk@nrot\pst@hbox
\ncput@iii
\endgroup
\pst@shortput}
\def\Mput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\Mput@ii}{\Mput@i}}}
\def\Mput@i#1{\addto@par{labelsep=#1}\Mput@ii}
\def\Mput@ii[#1]{\addto@par{ref={#1}}\Lput@v}
\def\aput@#1{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\aput@i#1}{\aput@ii#1}}}
\def\aput@i#1[#2]{\addto@par{labelsep=#2}\aput@ii#1}
\def\aput@ii#1{\@ifnextchar({\aput@iv#1}{\aput@iii#1}}
\def\aput@iii#1#2{\addto@par{nrot=#2}\@ifnextchar({\aput@iv#1}{#1}}
\def\aput@iv#1(#2){\addto@par{npos=#2}#1}
\def\aput{\aput@\naput@i}
\def\bput{\aput@\nbput@i}
\def\Aput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\Aput@i}{\naput@i}}}
\def\Aput@i[#1]{\addto@par{labelsep=#1}\naput@i}
\def\Bput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\Bput@i}{\nbput@i}}}
\def\Bput@i[#1]{\addto@par{labelsep=#1}\nbput@i}
\def\node@coor#1;#2\@nil{%
\pst@getnode{#1}\pst@tempg
\edef\pst@coor{%
\pst@nodedict
tx@NodeDict \pst@tempg known
{ \pst@tempg load \tx@GetCenter }
{ 0 0 }
ifelse
end }}
\def\Node@coor[#1]#2;#3\@nil{%
\begingroup
\psset{#1}%
\@ifnextchar\bgroup{\Node@@@coor}{\Node@@coor}#2\@nil
\endgroup
\let\pst@coor\pst@tempg}
\def\Node@@coor#1\@nil{%
\pst@getnode{#1}\pst@tempg
\xdef\pst@tempg{%
\pst@nodedict
tx@NodeDict \pst@tempg known
{ \psk@nodesepA \psk@angleA
\pst@tempg load \psk@nodeseptypeA \tx@GetEdge
\psk@offsetA \psk@angleA \tx@AddOffset
\pst@tempg load \tx@GetCenter
3 -1 roll add 3 1 roll add exch }
{ CP }
ifelse
end }}%
\def\Node@@@coor#1{%
\pst@@getcoor{#1}%
\def\psk@angleA{%
\pst@tempg load \tx@GetCenter \pst@coor
3 -1 roll sub 3 1 roll sub neg \tx@Atan}%
\Node@@coor}
\def\nput{\pst@object{nput}}
\def\nput@i#1#2{\pst@killglue\pst@makebox{\nput@ii{#1}{#2}}}
\def\nput@ii#1#2{%
\begingroup
\use@par
\psset@refangle{#1}%
\let\psk@angleA\psk@refangle
\edef\psk@nodesepA{\pst@number\pslabelsep}%
\def\psk@nodeseptypeA{0 }%
\pslabelsep\z@
\uput@vi
\Node@@coor#2\@nil
\let\pst@coor\pst@tempg
\leavevmode
\psput@special\pst@hbox
\endgroup
\ignorespaces}
\newcount\psrow
\newcount\pscol
\newcount\psmatrixcnt
\newskip\psrowsep
\newskip\pscolsep
\def\psset@colsep#1{\pssetlength\pscolsep{#1}}
\def\psset@rowsep#1{\pssetlength\psrowsep{#1}}
\psset@colsep{1.5cm}
\psset@rowsep{1.5cm}
\newif\ifpsmatrix
% DG/SR modification begin - Nov. 27, 1998 - Patch 8
%\let\mscount\@multicnt
\ifx\mscount\@undefined\let\mscount\@multicnt\fi
% DG/SR modification end
\def\psmatrix{%
  \begingroup
{\ifnum0=`}\fi % Don't want to expand any &.
\@ifnextchar[{\psmatrix@i}{\ifnum0=`{\fi}{}\psmatrix@ii}}
\def\psmatrix@i[#1]{%
\ifnum0=`{\fi}{}%
\psset{#1}%
\psmatrix@ii}
\def\psmatrix@ii{%
\KillGlue
\edef\psm@beginmath{%
\ifmmode$\m@th\ifinner\textstyle\else\displaystyle\fi\fi}%
\edef\psm@endmath{\ifmmode$\fi}%
\let\\\psm@cr
\advance\psmatrixcnt 1
\def\psm@thenode{M-\the\psmatrixcnt-\the\psrow-\the\pscol}%
\tabskip\z@
\psrow1
\pscol\z@
\psset@shortput{tablr}%
\leavevmode
\vbox\bgroup\halign\bgroup&%
\begingroup
\global\advance\pscol 1
\csname psrowhook\romannumeral\psrow\endcsname
\csname pscolhook\romannumeral\pscol\endcsname
\psm@beginnode##\psm@endnode\endgroup
\cr}
\def\endpsmatrix{%
\crcr\egroup\unskip\egroup
\endgroup}
\def\psm@cr{{\ifnum0=`}\fi\@ifnextchar[{\psm@@cr}{\psm@@@cr{}}}
\def\psm@@cr[#1]{\psm@@@cr{\vskip#1\relax}}
\def\psm@@@cr#1{%
\ifnum0=`{\fi}{}\cr
\noalign{%
\global\advance\psrow 1
\global\pscol\z@
\vskip\psrowsep
#1}}
\def\psm@beginnode{%
\@ifnextchar\psm@endnode
{\let\psm@endnode@i\relax\setbox\pst@hbox=\hbox{}}%
{\pst@object{psm@beginnode}}}
\def\psm@beginnode@i{%
\setbox\pst@hbox=\hbox\bgroup
\psm@beginmath
\begingroup
\ignorespaces}
\def\psm@endnode@i{%
\unskip
\endgroup
\psm@endmath
\egroup
\use@par
\@psttrue}
\def\psm@endnode{%
\@pstfalse
\psm@endnode@i
\ifnum\pscol>1 \hskip\pscolsep \fi
\psk@mnodesize
\hfil
\nodealigntrue
\if@pst
\csname mnode@\psk@mnode\endcsname
\else
\csname mnode@\psk@emnode\endcsname
\fi
\psk@mcol
\psk@@mnodesize}
\def\psspan#1{\mscount#1\relax\loop\ifnum\mscount>\@ne \sp@n\repeat}
\def\psset@name#1{\pst@getnode{#1}\psk@name}
\let\psk@name\relax
\def\psset@mcol#1{%
\ifx r#1\relax
\let\psk@mcol\relax
\else
\ifx l#1\relax
\let\psk@mcol\hfill
\else
\let\psk@mcol\hfil
\fi
\fi}
\psset@mcol{c}
\def\psset@mnodesize#1{%
\pssetlength\pst@dimg{#1}%
\ifdim\pst@dimg<\z@
\let\psk@mnodesize\relax
\let\psk@@mnodesize\relax
\else
\edef\psk@mnodesize{\noexpand\hbox to\number\pst@dimg sp\noexpand\bgroup}%
\let\psk@@mnodesize\egroup
\fi}
\psset@mnodesize{-1pt}
\def\mnode@R{\rnode@iii\Rnode@ii{\psm@thenode}}
\def\mnode@r{\rnode@iii\rnode@iv{\psm@thenode}}
\def\mnode@oval{\ovalnode@ii{\psm@thenode}}
\def\mnode@tri{\trinode@ii{\psm@thenode}}
\def\mnode@dia{\dianode@ii{\psm@thenode}}
\def\mnode@C{{\nodealigntrue\cnode@ii(\z@,\z@){\psk@radius}{\psm@thenode}}}
\def\mnode@f{{\nodealigntrue\fnode@ii(\z@,\z@){\psm@thenode}}}
\def\mnode@circle{\circlenode@ii{\psm@thenode}}
\def\mnode@p{\pnode(\z@,\z@){\psm@thenode}}
% DG/SR modification begin - Jul. 22, 1997 - Patch 1
\def\mnode@dot{\dotnode@ii(\z@,\z@){\psm@thenode}}
% DG/SR modification end
\def\mnode@none{\box\pst@hbox}
\def\psset@mnode#1{%
\@ifundefined{mnode@#1}%
{\@pstrickserr{\string\psmatrix\space node `#1' not defined.}\@ehpa}%
{\edef\psk@mnode{#1}}}
\def\psset@emnode#1{%
\@ifundefined{mnode@#1}%
{\@pstrickserr{\string\psmatrix\space node `#1' not defined.}\@ehpa}%
{\edef\psk@emnode{#1}}}
\psset@mnode{R}
\psset@emnode{none}
%%%% FROM pst-coil.tex
\def\nccoil{\pst@object{nccoil}}
\def\nccoil@i{\check@arrow{\nccoil@ii}}
\def\nccoil@ii#1#2{\nc@object{Open}{#1}{#2}{.5}{%
\tx@NCCoor
tx@Dict begin
% DG/SR modification begin - Mar. 19, 1998 - Patch 5
4 2 roll
% DG/SR modification end
\psk@coilwidth \pscoilheight
\psk@coilarmA \psk@coilarmB
\psk@coilaspect \psk@coilinc
\pst@coildict \tx@Coil end
end}}
\def\nczigzag{\pst@object{nczigzag}}
\def\nczigzag@i{\check@arrow{\nczigzag@ii}}
\def\nczigzag@ii#1#2{\nc@object{Open}{#1}{#2}{.5}{%
\tx@NCCoor
tx@Dict begin
% DG/SR modification begin - Mar. 19, 1998 - Patch 5
4 2 roll
% DG/SR modification end
\pscoilheight
\psk@coilwidth
\psk@coilarmA
\psk@coilarmB
\pst@coildict \tx@ZigZag end
\psline@iii
\tx@Line
end}}
\catcode`\@=\TheAtCode\relax
\endinput
%%
%% END pst-node.tex

pstricks.tex
%% BEGIN: pstricks.tex
%%
%% PostScript macros for Generic TeX: main input file for PSTricks 97.
%% See the PSTricks User's Guide for description.
%% This uses the header file `pstricks.pro'.
%%
\def\fileversion{97 patch 10}
\def\filedate{1999/03/24}
%%
%% COPYRIGHT 1993, 1994, 1999 by Timothy Van Zandt, tvz@nwu.edu.
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN
%% archives in directory macros/latex/base/lppl.txt.
%%
\csname PSTricksLoaded\endcsname
\let\PSTricksLoaded\endinput
\edef\PstAtCode{\the\catcode`\@}
\catcode`\@=11\relax
\expandafter\ifx\csname @latexerr\endcsname\relax
\long\def\@ifundefined#1#2#3{\expandafter\ifx\csname
#1\endcsname\relax#2\else#3\fi}
\def\@namedef#1{\expandafter\def\csname #1\endcsname}
\def\@nameuse#1{\csname #1\endcsname}
\def\@eha{%
Your command was ignored.^^J
Type \space I <command> <return> \space to replace
it with another command,^^J
or \space <return> \space to continue without it.}
\def\@spaces{\space\space\space\space}
\def\typeout#1{\immediate\write\@unused{#1}}
\alloc@7\write\chardef\sixt@@n\@unused
\def\@empty{}
\def\@gobble#1{}
\def\@nnil{\@nil}
\def\@ifnextchar#1#2#3{%
\let\@tempe#1\def\@tempa{#2}\def\@tempb{#3}\futurelet\@tempc\@ifnch}
\def\@ifnch{%
\ifx\@tempc\@sptoken
\let\@tempd\@xifnch
\else
\ifx\@tempc\@tempe \let\@tempd\@tempa \else \let\@tempd\@tempb \fi
\fi
\@tempd}
\begingroup
\def\:{\global\let\@sptoken= } \:
\def\:{\@xifnch} \expandafter\gdef\: {\futurelet\@tempc\@ifnch}
\endgroup
\fi
\typeout{`PSTricks' v\fileversion\space\space <\filedate> (tvz)}
\def\@pstrickserr#1#2{%
\begingroup
\newlinechar`\^^J
\edef\pst@tempc{#2}%
\expandafter\errhelp\expandafter{\pst@tempc}%
\typeout{%
PSTricks error. \space See User's Guide for further information.^^J
\@spaces\@spaces\@spaces\@spaces
Type \space H <return> \space for immediate help.}%
\errmessage{#1}%
\endgroup}
\def\@ehpa{%
Your command was ignored. Default value substituted.^^J
Type \space <return> \space to procede.}
\def\@ehpb{%
Your command was ignored. Will recover best I can.^^J
Type \space <return> \space to procede.}
\def\@ehpc{%
You better fix this before proceding.^^J
See the PSTricks User's Guide or ask your system administrator for help.^^J
Type \space X <return> \space to quit.}
\def\pst@misplaced#1{\@pstrickserr{Misplaced \string#1 command}\@ehpb}
\newdimen\pst@dima
\newdimen\pst@dimb
\newdimen\pst@dimc
\newdimen\pst@dimd
\newdimen\pst@dimg
\newdimen\pst@dimh
\newbox\pst@hbox
\newbox\pst@boxg
\newcount\pst@cnta
\newcount\pst@cntb
\newcount\pst@cntc
\newcount\pst@cntd
\newcount\pst@cntg
\newcount\pst@cnth
\newif\if@pst
\newtoks\pst@toks
\newif\if@star
\def\pst@ifstar#1{%
\@ifnextchar*{\@startrue\def\next*{#1}\next}{\@starfalse#1}}
\def\pst@expandafter#1#2{%
\def\next{#1}%
\edef\@tempa{#2}%
\ifx\@tempa\@empty
\@pstrickserr{Unexpected empty argument!}\@ehpb
\def\@tempa{\@empty}%
\fi
\expandafter\next\@tempa}
\def\pst@dimtonum#1#2{\edef#2{\pst@@dimtonum#1}}
\def\pst@@dimtonum#1{\expandafter\pst@@@dimtonum\the#1}
{\catcode`\p=12 \catcode`\t=12 \global\@namedef{pst@@@dimtonum}#1pt{#1}}
\def\pst@pyth#1#2#3{%
\ifdim#1>#2\pst@@pyth#1#2#3\else\pst@@pyth#2#1#3\fi}
\def\pst@@pyth#1#2#3{%
\ifdim4#1>9#2%
#3=#1\advance#3 .2122#2%
\else
#3=.8384#1\advance#3 .5758#2%
\fi}
\def\pst@divide#1#2#3{%
\pst@@divide{#1}{#2}%
\pst@dimtonum\pst@dimg{#3}}
\def\pst@@divide#1#2{%
\pst@dimg=#1\relax
\pst@dimh=#2\relax
\pst@cntg=\pst@dimh
\pst@cnth=67108863
\pst@@@divide\pst@@@divide\pst@@@divide\pst@@@divide
\divide\pst@dimg\pst@cntg}
\def\pst@@@divide{%
\ifnum
\ifnum\pst@dimg<\z@-\fi\pst@dimg<\pst@cnth
\multiply\pst@dimg\sixt@@n
\else
\divide\pst@cntg\sixt@@n
\fi}
\def\pst@configerr#1{%
\@pstrickserr{\string#1 not defined in pstricks.con}\@ehpc}
% % \begin{macrocode}
\def\pstVerb#1{\pst@configerr\pstVerb}
\def\pstverb#1{\pst@configerr\pstverb}
\def\pstverbscale{\pst@configerr\pstverbscale}
\def\pstrotate{\pst@configerr\pstrotate}
\def\pstheader#1{\pst@configerr\pstheader}
\def\pstdriver{\pst@configerr\pstdriver}
\@ifundefined{pstcustomize}%
{\def\pstcustomize{\endinput\let\pstcustomize\relax}}{}
\input pstricks.con
\newif\ifPSTricks
\PSTrickstrue
\def\PSTricksOff{%
\def\pstheader##1{}%
\def\pstverb##1{}%
\def\pstVerb##1{}%
\PSTricksfalse}
\@ifundefined{pst@def}{\def\pst@def#1<#2>{\@namedef{tx@#1}{#2 }}}{}
\@ifundefined{pst@ATH}{\def\pst@ATH<#1>{}}{}
\pstheader{pstricks.pro}
\def\pst@dict{tx@Dict begin }
\def\pst@theheaders{pstricks.pro}
\def\pst@Verb#1{\pstVerb{\pst@dict #1 end}}
\def\tx@Atan{Atan }
\def\tx@Div{Div }
\def\tx@NET{NET }
\def\tx@Pyth{Pyth }
\def\tx@PtoC{PtoC }
\def\tx@PathLength@{PathLength@ }
\def\tx@PathLength{PathLength }
\pst@dimg=\pstunit\relax
\ifdim\pst@dimg=1bp
\def\pst@stp{.996264 dup scale}
\else
\edef\pst@stp{1 \pst@@dimtonum\pst@dimg\space div dup scale}
\fi
\def\tx@STP{STP }
\def\tx@STV{STV }
\def\pst@number#1{\pst@@dimtonum#1\space}
\def\pst@checknum#1#2{%
\edef\next{#1}%
\ifx\next\@empty
\let\pst@num\z@
\else
\expandafter\pst@@checknum\next..\@nil
\fi
\ifnum\pst@num=\z@
\@pstrickserr{Bad number: `#1'. 0 substituted.}\@ehpa
\def#2{0 }%
\else
\edef#2{\ifnum\pst@num=\tw@-\fi\the\pst@cntg.%
\expandafter\@gobble\the\pst@cnth\space}%
\fi}
\def\pst@@checknum{%
\@ifnextchar-%
{\let\pst@num\tw@\expandafter\pst@@@checknum\@gobble}%
{\let\pst@num\@ne\pst@@@checknum}}
\def\pst@@@checknum#1.#2.#3\@nil{%
\afterassignment\pst@@@@checknum\pst@cntg=0#1\relax\@nil
\afterassignment\pst@@@@checknum\pst@cnth=1#2\relax\@nil}
\def\pst@@@@checknum#1\relax\@nil{%
\ifx\@nil#1\@nil\else\let\pst@num\z@\fi}
\def\pst@getnumii#1 #2 #3\@nil{%
\pst@checknum{#1}\pst@tempg
\pst@checknum{#2}\pst@temph}
\def\pst@getnumiii#1 #2 #3 #4\@nil{%
\pst@checknum{#1}\pst@tempg
\pst@checknum{#2}\pst@temph
\pst@checknum{#3}\pst@tempi}
\def\pst@getnumiv#1 #2 #3 #4 #5\@nil{%
\pst@checknum{#1}\pst@tempg
\pst@checknum{#2}\pst@temph
\pst@checknum{#3}\pst@tempi
\pst@checknum{#4}\pst@tempj}
\def\pst@getdimnum#1 #2 #3\@nil{%
\pssetlength\pst@dimg{#1}%
\pst@checknum{#2}\pst@tempg}
% DG/SR modification begin - Jan. 7, 1998 - Patch 9
% Missing from pstricks.bug 0.93
%\def\pst@getscale#1#2{%
%\pst@expandafter\pst@getnumii{#1 #1} {} {} {}\@nil
%\@psttrue
%\ifdim\pst@tempg\p@=\z@
%\@pstrickserr{Bad scaling argument `#1'}\@ehpa
%\def\pst@tempg{1 }%
%\@pstfalse
%\fi
%\ifdim\pst@temph\p@=\z@
%\if@pst\@pstrickserr{Bad scaling argument `#1'}\@ehpa\fi
%\def\pst@temph{1 }%
%\fi
%\edef#2{\pst@tempg\space \pst@temph\space scale }%
%\ifdim\pst@tempg\p@=\p@ \ifdim\pst@temph\p@=\p@
%\def#2{}%
%\fi\fi}
\def\pst@getscale#1#2{%
\edef\pst@tempg{#1}%
\ifx\pst@tempg\@none
\def#2{}%
\else
\pst@expandafter\pst@getnumii{#1 #1} {} {} {}\@nil
\ifdim\pst@tempg\p@=\z@
\@pstrickserr{Bad scaling argument `#1'}\@ehpa
\def#2{}%
\else
\ifdim\pst@temph\p@=\z@
\@pstrickserr{Bad scaling argument `#1'}\@ehpa
\def#2{}%
\else
\edef#2{\pst@tempg\space \pst@temph\space scale }%
\fi
\fi
\fi}
% DG/SR modification end
\def\pst@getint#1#2{%
\pst@cntg=#1\relax
\edef#2{\the\pst@cntg\space}}
\begingroup
\catcode`\{=12
\catcode`\}=12
\catcode`\[=1
\catcode`\]=2
\gdef\pslbrace[{ ]
\gdef\psrbrace[} ]
\endgroup
\def\@newcolor#1#2{%
\expandafter\edef\csname #1\endcsname{\noexpand\pst@color{#2}}%
\expandafter\edef\csname color@#1\endcsname{#2}%
\ignorespaces}
\def\pst@color#1{%
\def\pst@currentcolor{#1}\pstVerb{#1}\aftergroup\pst@endcolor}
\def\pst@endcolor{\pstVerb{\pst@currentcolor}}
\def\pst@currentcolor{0 setgray}
\def\altcolormode{%
\def\pst@color##1{%
\pstVerb{gsave ##1}\aftergroup\pst@endcolor}%
\def\pst@endcolor{\pstVerb{\pst@grestore}}}
\def\pst@grestore{%
currentpoint
matrix currentmatrix
currentfont
grestore
setfont
setmatrix
moveto}
\def\pst@usecolor#1{\csname color@#1\endcsname\space}
\def\newgray#1#2{%
\pst@checknum{#2}\pst@tempg
\@newcolor{#1}{\pst@tempg setgray}}
\def\newrgbcolor#1#2{%
\pst@expandafter\pst@getnumiii{#2} {} {} {} {}\@nil
\@newcolor{#1}{\pst@tempg \pst@temph \pst@tempi setrgbcolor}}
\def\newhsbcolor#1#2{%
\pst@expandafter\pst@getnumiii{#2} {} {} {} {}\@nil
\@newcolor{#1}{\pst@tempg \pst@temph \pst@tempi sethsbcolor}}
\def\newcmykcolor#1#2{%
\pst@expandafter\pst@getnumiv{#2} {} {} {} {} {}\@nil
\@newcolor{#1}{\pst@tempg \pst@temph \pst@tempi \pst@tempj setcmykcolor}}
\newgray{black}{0}
\newgray{darkgray}{.25}
\newgray{gray}{.5}
\newgray{lightgray}{.75}
\newgray{white}{1}
\newrgbcolor{red}{1 0 0}
\newrgbcolor{green}{0 1 0}
\newrgbcolor{blue}{0 0 1}
\newrgbcolor{yellow}{1 1 0}
\newrgbcolor{cyan}{0 1 1}
\newrgbcolor{magenta}{1 0 1}
\def\psset#1{\@psset#1,\@nil\ignorespaces}
\def\@psset#1,{%
\@@psset#1==\@nil
\@ifnextchar\@nil{\@gobble}{\@psset}}
\def\@@psset#1=#2=#3\@nil{%
\@ifundefined{psset@#1}%
{\@pstrickserr{Graphics parameter `#1' not defined.}\@ehpa}%
{\@nameuse{psset@#1}{#2}}}%
\def\psset@style#1{%
\@ifundefined{pscs@#1}%
{\@pstrickserr{Custom style `#1' undefined}\@ehpa}%
{\@nameuse{pscs@#1}}}
\def\newpsstyle#1#2{\@namedef{pscs@#1}{\psset{#2}}}
\def\@none{none}
\def\pst@getcolor#1#2{%
\@ifundefined{color@#1}%
{\@pstrickserr{Color `#1' not defined}\@eha}%
{\edef#2{#1}}}
\newdimen\psunit \psunit 1cm
\newdimen\psxunit \psxunit 1cm
\newdimen\psyunit \psyunit 1cm
\let\psrunit\psunit
\def\pstunit@off{\let\@psunit\ignorespaces\ignorespaces}
\def\pssetlength#1#2{%
\let\@psunit\psunit
\afterassignment\pstunit@off
#1 #2\@psunit}
\def\psaddtolength#1#2{%
\let\@psunit\psunit
\afterassignment\pstunit@off
\advance#1 #2\@psunit}
\def\pssetxlength#1#2{%
\let\@psunit\psxunit
\afterassignment\pstunit@off
#1 #2\@psunit}
\def\pssetylength#1#2{%
\let\@psunit\psyunit
\afterassignment\pstunit@off
#1 #2\@psunit}
\def\psset@unit#1{%
\pssetlength\psunit{#1}%
\psxunit=\psunit
\psyunit=\psunit}
\def\psset@runit#1{\pssetlength\psrunit{#1}}
\def\psset@xunit#1{\pssetxlength\psxunit{#1}}
\def\psset@yunit#1{\pssetylength\psyunit{#1}}
\def\pst@getlength#1#2{%
\pssetlength\pst@dimg{#1}%
\edef#2{\pst@number\pst@dimg}}
\def\pst@@getlength#1#2{%
\pssetlength\pst@dimg{#1}%
\edef#2{\number\pst@dimg sp}}
\def\pst@getcoor#1#2{\pst@@getcoor{#1}\let#2\pst@coor}
\def\pst@coor{0 0 }
\def\pst@getcoors#1#2{%
\def\pst@aftercoors{\addto@pscode{#1 \pst@coors }#2}%
\def\pst@coors{}%
\pst@@getcoors}
\def\pst@@getcoors(#1){%
\pst@@getcoor{#1}%
\edef\pst@coors{\pst@coor\pst@coors}%
\@ifnextchar({\pst@@getcoors}{\pst@aftercoors}}
\def\pst@getangle#1#2{\pst@@getangle{#1}\let#2\pst@angle}
\def\pst@angle{0 }
\def\cartesian@coor#1,#2,#3\@nil{%
\pssetxlength\pst@dimg{#1}%
\pssetylength\pst@dimh{#2}%
\edef\pst@coor{\pst@number\pst@dimg \pst@number\pst@dimh}}
\def\NormalCoor{%
\def\pst@@getcoor##1{\pst@expandafter\cartesian@coor{##1},\relax,\@nil}%
\def\pst@@getangle##1{%
\pst@checknum{##1}\pst@angle
\edef\pst@angle{\pst@angle \pst@angleunit}}%
\def\psput@##1{\pst@@getcoor{##1}\leavevmode\psput@cartesian}}
\NormalCoor
\def\degrees{\@ifnextchar[{\@degrees}{\def\pst@angleunit{}}}
\def\@degrees[#1]{%
\pst@checknum{#1}\pst@tempg
\edef\pst@angleunit{360 \pst@tempg div mul }%
\ignorespaces}
\def\radians{\def\pst@angleunit{57.2956 mul }}
\def\pst@angleunit{}
\def\SpecialCoor{%
\def\pst@@getcoor##1{%
\begingroup
\pst@activecoor
\xdef\pst@tempg{##1}%
\endgroup
\expandafter\special@coor\pst@tempg||\@nil}%
\def\pst@@getangle##1{%
\begingroup
\pst@activecoor
\xdef\pst@tempg{##1}%
\endgroup
\expandafter\special@angle\pst@tempg\@empty)\@nil}%
\def\psput@##1{\pst@@getcoor{##1}\leavevmode\psput@special}}
\begingroup
\catcode`\|=13
\catcode`\;=13
\catcode`\!=13
\gdef\pst@activecoor{%
\def|{\string|}%
\def;{\string;}%
\def!{\string!}}
\endgroup
\def\special@coor#1|#2|#3\@nil{%
\ifx#3|\relax
\mixed@coor{#1}{#2}%
\else
\special@@coor#1;;\@nil
\fi}
\def\special@@coor#1{%
\ifcat#1a\relax
\def\next{\node@coor#1}%
\else
\ifx#1[\relax
\def\next{\Node@coor[}%
\else
\ifx#1!\relax
\def\next{\raw@coor}%
\else
\def\next{\special@@@coor#1}%
\fi
\fi
\fi
\next}
\def\special@@@coor#1;#2;#3\@nil{%
\ifx#3;\relax
\polar@coor{#1}{#2}%
\else
\cartesian@coor#1,\relax,\@nil
\fi}
\def\mixed@coor#1#2{%
\begingroup
% DG/SR modification begin - Oct. 27, 1997 - Patch 6
%\specialcoor@ii#1;;\@nil
%\let\pst@tempa\pst@coor
%\specialcoor@ii#2;;\@nil
\special@@coor#1;;\@nil
\let\pst@tempa\pst@coor
\special@@coor#2;;\@nil
% DG/SR modification end
\xdef\pst@tempg{\pst@tempa pop \pst@coor exch pop }%
\endgroup
\let\pst@coor\pst@tempg}
\def\polar@coor#1#2{%
\pssetlength\pst@dimg{#1}%
\pst@@getangle{#2}%
\edef\pst@coor{\pst@number\pst@dimg \pst@angle \tx@PtoC}}
\def\raw@coor#1;#2\@nil{%
\edef\pst@coor{%
#1 \pst@number\psyunit mul exch \pst@number\psxunit mul exch }}
\def\node@coor#1\@nil{%
\@pstrickserr{You must load `pst-node.tex' to use node coordinates.}\@ehps
\def\pst@coor{0 0 }}
\def\Node@coor{\node@coor}
\def\special@angle#1#2)#3\@nil{%
\ifx!#1\relax
\edef\pst@angle{#2 \pst@angleunit}%
\else
\ifx(#1\relax
\pst@@getcoor{#2}%
\edef\pst@angle{\pst@coor exch \tx@Atan}%
\else
\pst@checknum{#1#2}\pst@angle
\edef\pst@angle{\pst@angle \pst@angleunit}%
\fi
\fi}
\def\Cartesian{%
\def\cartesian@coor##1,##2,##3\@nil{%
\pssetxlength\pst@dimg{##1}%
\pssetylength\pst@dimh{##2}%
\edef\pst@coor{\pst@number\pst@dimg \pst@number\pst@dimh}}%
\@ifnextchar({\Cartesian@}{}}
\def\Cartesian@(#1,#2){%
\pssetxlength\psxunit{#1}%
\pssetylength\psyunit{#2}%
\ignorespaces}
\def\Polar{%
\def\psput@cartesian{\psput@special}%
\def\cartesian@coor##1,##2,##3\@nil{\polar@coor{##1}{##2}}}%
\def\psset@origin#1{%
\pst@@getcoor{#1}%
\edef\psk@origin{\pst@coor \tx@NET }}
\def\psk@origin{}
\newif\ifswapaxes
\def\psset@swapaxes#1{%
\@nameuse{@pst#1}%
\if@pst
\def\psk@swapaxes{-90 rotate -1 1 scale }%
\else
\def\psk@swapaxes{}%
\fi}
\psset@swapaxes{false}
\newif\ifshowpoints
\def\psset@showpoints#1{\@nameuse{showpoints#1}}
\psset@showpoints{false}
\let\pst@setrepeatarrowsflag\relax
\def\psset@border#1{%
\pst@getlength{#1}\psk@border
\pst@setrepeatarrowsflag}
\psset@border{0pt}
\def\psset@bordercolor#1{\pst@getcolor{#1}\psbordercolor}
\psset@bordercolor{white}
\newif\ifpsdoubleline
\def\psset@doubleline#1{%
\@nameuse{psdoubleline#1}%
\pst@setrepeatarrowsflag}
\psset@doubleline{false}
\def\psset@doublesep#1{\def\psdoublesep{#1}}
\psset@doublesep{1.25\pslinewidth}
\def\psset@doublecolor#1{\pst@getcolor{#1}\psdoublecolor}
\psset@doublecolor{white}
\newif\ifpsshadow
\def\psset@shadow#1{%
\@nameuse{psshadow#1}%
\pst@setrepeatarrowsflag}
\psset@shadow{false}
\def\psset@shadowsize#1{\pst@getlength{#1}\psk@shadowsize}
\psset@shadowsize{3pt}
\def\psset@shadowangle#1{\pst@getangle{#1}\psk@shadowangle}
\psset@shadowangle{-45}
\def\psset@shadowcolor#1{\pst@getcolor{#1}\psshadowcolor}
\psset@shadowcolor{darkgray}
\def\pst@repeatarrowsflag{\z@}
\def\pst@setrepeatarrowsflag{%
\edef\pst@repeatarrowsflag{%
\ifdim\psk@border\p@>\z@ 1\else\ifpsdoubleline 1\else
\ifpsshadow 1\else \z@\fi\fi\fi}}
\def\psls@none{}
\newdimen\pslinewidth
\def\psset@linewidth#1{\pssetlength\pslinewidth{#1}}
\psset@linewidth{.8pt}
\def\psset@linecolor#1{\pst@getcolor{#1}\pslinecolor}
\psset@linecolor{black}
\def\psls@solid{0 setlinecap stroke }
\def\pst@missing{%
\z@
\@pstrickserr{Missing number or dimension. 0 substituted}\@ehpa}
\def\psset@dash#1{%
\pst@expandafter\psset@@dash{#1} {\pst@missing} {\pst@missing} {}\@nil
\edef\psk@dash{\pst@number\pst@dimg \pst@number\pst@dimh}}
\def\psset@@dash#1 #2 #3\@nil{%
\pssetlength\pst@dimg{#1}%
\pssetlength\pst@dimh{#2}}
\psset@dash{5pt 3pt}
\newif\ifpsdashadjust
\def\psset@dashadjust#1{\@nameuse{psdashadjust#1}}
\psset@dashadjust{true}
\def\psls@dashed{%
\ifpsdashadjust
\psk@dash \pst@linetype\space \tx@DashLine
\else
[ \psk@dash ] 0 setdash stroke
\fi}
\def\tx@DashLine{DashLine }
\def\psset@dotsep#1{\pst@getlength{#1}\psk@dotsep}
\psset@dotsep{3pt}
\def\psls@dotted{%
\ifpsdashadjust
\psk@dotsep \pst@linetype\space \tx@DotLine
\else
[ 0 \psk@dotsep CLW add ] 0 setdash 1 setlinecap stroke
\fi}
\def\tx@DotLine{DotLine }
\def\psset@linestyle#1{%
\@ifundefined{psls@#1}%
{\@pstrickserr{Line style `#1' not defined}\@eha}%
{\edef\pslinestyle{#1}}}
\psset@linestyle{solid}
\def\psfs@none{}
\def\psset@fillcolor#1{\pst@getcolor{#1}\psfillcolor}
\psset@fillcolor{white}
\def\psfs@solid{\pst@fill{\pst@usecolor\psfillcolor fill}}
\def\psset@hatchwidth#1{\pst@getlength{#1}\psk@hatchwidth}
\psset@hatchwidth{.8pt}
\def\psset@hatchsep#1{\pst@getlength{#1}\psk@hatchsep}
\psset@hatchsep{4pt}
\def\psset@hatchcolor#1{\pst@getcolor{#1}\pshatchcolor}
\psset@hatchcolor{black}
\def\psset@hatchangle#1{\pst@getangle{#1}\psk@hatchangle}
\psset@hatchangle{45}
\def\pst@linefill{%
\psk@hatchangle rotate
\psk@hatchwidth SLW
\pst@usecolor\pshatchcolor
\psk@hatchsep \tx@LineFill}
\def\psfs@vlines{\pst@fill\pst@linefill}
\@namedef{psfs@vlines*}{\psfs@solid \psfs@vlines}
\def\psfs@hlines{\pst@fill{90 rotate \pst@linefill}}
\@namedef{psfs@hlines*}{\psfs@solid \psfs@hlines}
\def\psfs@crosshatch{\psfs@vlines \psfs@hlines}
\@namedef{psfs@crosshatch*}{\psfs@solid \psfs@vlines \psfs@hlines}
\def\tx@LineFill{LineFill }
\def\psset@fillstyle#1{%
\edef\pst@tempg{#1}\def\pst@temph{none}%
\ifx\pst@tempg\pst@temph
\let\psk@fillstyle\relax
\else
\@ifundefined{psfs@#1}%
{\@pstrickserr{Undefined fill style: `#1'}\@eha}%
{\edef\psk@fillstyle{\expandafter\noexpand\csname psfs@#1\endcsname}}%
\fi}
\def\psset@addfillstyle#1{%
\@ifundefined{psfs@#1}%
{\@pstrickserr{Undefined fill style: `#1'}\@eha}%
{\edef\psk@fillstyle{%
\expandafter\noexpand\psk@fillstyle
\expandafter\noexpand\csname psfs@#1\endcsname}}}
\psset@fillstyle{none}
\def\psset@arrows#1{%
\begingroup
\pst@activearrows
\xdef\pst@tempg{#1}%
\endgroup
\expandafter\psset@@arrows\pst@tempg\@empty-\@empty\@nil
\if@pst\else
\@pstrickserr{Bad arrows specification: #1}\@ehpa
\fi}
\def\psset@@arrows#1-#2\@empty#3\@nil{%
\@psttrue
\def\next##1,#1-##2,##3\@nil{\def\pst@tempg{##2}}%
\expandafter\next\pst@arrowtable,#1-#1,\@nil
\@ifundefined{psas@\pst@tempg}%
{\@pstfalse\def\psk@arrowA{}}%
{\let\psk@arrowA\pst@tempg}%
\@ifundefined{psas@#2}%
{\@pstfalse\def\psk@arrowB{}}%
{\def\psk@arrowB{#2}}}
\def\psk@arrowA{}
\def\psk@arrowB{}
\def\pst@arrowtable{,<->,<<->>,>-<,>>-<<,(-),[-]}
\begingroup
\catcode`\<=13
\catcode`\>=13
\catcode`\|=13
\gdef\pst@activearrows{\def<{\string<}\def>{\string>}\def|{\string|}}
\endgroup
\def\tx@BeginArrow{BeginArrow }
\def\tx@EndArrow{EndArrow }
\def\psset@arrowscale#1{\pst@getscale{#1}\psk@arrowscale}
\psset@arrowscale{1}
\def\psset@arrowsize#1{%
\pst@expandafter\pst@getdimnum{#1} 0 {} {}\@nil
\edef\psk@arrowsize{\pst@number\pst@dimg \pst@tempg}}
\psset@arrowsize{1.5pt 2}
\def\psset@arrowlength#1{\pst@checknum{#1}\psk@arrowlength}
\psset@arrowlength{1.4}
\def\psset@arrowinset#1{\pst@checknum{#1}\psk@arrowinset}%
\psset@arrowinset{.4}
\def\tx@Arrow{Arrow }
\@namedef{psas@>}{%
false \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow}
\@namedef{psas@>>}{%
false \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow
0 h T
gsave
newpath
false \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow
CP
grestore
CP newpath moveto
2 copy
L
stroke
moveto}
\@namedef{psas@<}{%
true \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow}
\@namedef{psas@<<}{%
true \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow
CP newpath moveto 0 a neg L stroke 0 h neg T
false \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow}
\def\psset@tbarsize#1{%
\pst@expandafter\pst@getdimnum{#1} 0 {} {}\@nil
\edef\psk@tbarsize{\pst@number\pst@dimg \pst@tempg}}
\psset@tbarsize{2pt 5}
\def\tx@Tbar{Tbar }
\@namedef{psas@|}{\psk@tbarsize \tx@Tbar}
\@namedef{psas@|*}{0 CLW -2 div T \psk@tbarsize \tx@Tbar}
\@namedef{psas@>|}{%
\psk@tbarsize \tx@Tbar
0 CLW 2 div T
newpath
false \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow}
\@namedef{psas@>|*}{%
0 CLW -2 div T
\psk@tbarsize \tx@Tbar
0 CLW 2 div T
newpath
false \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow}
\edef\pst@arrowtable{\pst@arrowtable,|<*->|*,|<->|}
\def\psset@bracketlength#1{\pst@checknum{#1}\psk@bracketlength}
\psset@bracketlength{.15}
\def\tx@Bracket{Bracket }
\@namedef{psas@]}{\psk@bracketlength \psk@tbarsize \tx@Bracket}
\def\psset@rbracketlength#1{\pst@checknum{#1}\psk@rbracketlength}
\psset@rbracketlength{.15}
\def\tx@RoundBracket{RoundBracket }
\@namedef{psas@)}{\psk@rbracketlength \psk@tbarsize \tx@RoundBracket}
\def\psas@c{1 \psas@@c}
\def\psas@cc{0 CLW 2 div T 1 \psas@@c}
\def\psas@C{2 \psas@@c}
\def\psas@@c{%
setlinecap
0 0 moveto
0 CLW 2 div L
stroke
0 0 moveto}
\def\psas@{}
\psset@arrows{-}
\def\tx@SD{SD }
\def\tx@EndDot{EndDot }
\def\psas@oo{{\pst@usecolor\psfillcolor true} true \psk@dotsize \tx@EndDot}
\def\psas@o{{\pst@usecolor\psfillcolor true} false \psk@dotsize \tx@EndDot}
\@namedef{psas@**}{{false} true \psk@dotsize \tx@EndDot}
\@namedef{psas@*}{{false} false \psk@dotsize \tx@EndDot}
\def\pst@par{}
\def\addto@par#1{%
\ifx\pst@par\@empty
\def\pst@par{#1}%
\else
\expandafter\def\expandafter\pst@par\expandafter{\pst@par,#1}%
\fi}
\def\addbefore@par#1{%
\ifx\pst@par\@empty
\def\pst@par{#1}%
\else
\toks@{#1}%
\pst@toks\expandafter{\pst@par}%
\edef\pst@par{\the\toks@,\the\pst@toks}%
\fi}
\def\use@par{%
\ifx\pst@par\@empty\else
\expandafter\@psset\pst@par,\@nil
\def\pst@par{}%
\fi}
\def\pst@object#1{%
\pst@ifstar{%
\@ifnextchar[%
{\pst@@object{#1}}%
{\def\pst@par{}\@nameuse{#1@i}}}}
\def\pst@@object#1[#2]{%
\def\pst@par{#2}%
\@ifnextchar+{\@nameuse{#1@i}}{\@nameuse{#1@i}}}
\def\newpsobject#1#2#3{%
\@ifundefined{#2@i}%
{\@pstrickserr{Graphics object `#2' not defined}\@eha}{%
\@namedef{#1}{\pst@object{#1}}%
\@namedef{#1@i}{\addbefore@par{#3}\@nameuse{#2@i}}}%
\ignorespaces}
\def\pst@getarrows#1{\@ifnextchar({#1}{\pst@@getarrows{#1}}}
\def\pst@@getarrows#1#2{\addto@par{arrows=#2}#1}
\def\begin@ClosedObj{%
\leavevmode
\pst@killglue
\begingroup
\use@par
\solid@star
\ifpsdoubleline \pst@setdoublesep \fi
\init@pscode}
\def\end@ClosedObj{%
\ifpsshadow \pst@closedshadow \fi
\ifdim\psk@border\p@>\z@ \pst@addborder \fi
\psk@fillstyle
\pst@stroke
\ifpsdoubleline \pst@doublestroke \fi
\ifshowpoints
% DG modification begin - Mar. 4, 1995
%\addto@pscode{Points aload length 2 div cvi /N ED \psdots@iii}%
\pst@OpenShowPoints
% DG modification end
\fi
\use@pscode
\endgroup
\ignorespaces}
\def\begin@OpenObj{%
\begin@ClosedObj
\let\pst@linetype\pst@arrowtype
\pst@addarrowdef}
\def\begin@AltOpenObj{%
\begin@ClosedObj
\def\pst@repeatarrowsflag{\z@}%
\def\pst@linetype{0}}
\def\end@OpenObj{%
\ifpsshadow \pst@openshadow \fi
\ifdim\psk@border\p@>\z@ \pst@addborder \fi
\psk@fillstyle
\pst@stroke
\ifpsdoubleline \pst@doublestroke \fi
\ifnum\pst@repeatarrowsflag>\z@ \pst@repeatarrows \fi
\ifshowpoints \pst@OpenShowPoints \fi
\use@pscode
\endgroup
\ignorespaces}
\def\begin@SpecialObj{%
\leavevmode
\pst@killglue
\begingroup
\use@par
\init@pscode}
\def\end@SpecialObj{%
\use@pscode
\endgroup
\ignorespaces}
\def\pst@code{}%
\def\init@pscode{%
\addto@pscode{%
\pst@number\pslinewidth SLW
\pst@usecolor\pslinecolor}}
\def\addto@pscode#1{\xdef\pst@code{\pst@code#1\space}}
\def\use@pscode{%
\pstverb{%
\pst@dict
\tx@STP
\pst@newpath
\psk@origin
\psk@swapaxes
\pst@code
end}%
\gdef\pst@code{}}
\def\pst@newpath{newpath }
\def\pst@@killglue{\unskip\ifdim\lastskip>\z@\expandafter\pst@@killglue\fi}
\def\KillGlue{\let\pst@killglue\pst@@killglue}
\def\DontKillGlue{\let\pst@killglue\relax}
\DontKillGlue
\def\solid@star{%
\if@star
\pslinewidth=\z@
\psdoublelinefalse
\def\pslinestyle{none}%
\def\psk@fillstyle{\psfs@solid}%
\let\psfillcolor\pslinecolor
\fi}
\def\pst@setdoublesep{%
\pst@getlength\psdoublesep\psdoublesep
\pslinewidth=2\pslinewidth
\advance\pslinewidth\psdoublesep\p@
\let\pst@setdoublesep\relax}
\def\tx@Shadow{Shadow }
\def\pst@closedshadow{%
\addto@pscode{%
gsave
\psk@shadowsize \psk@shadowangle \tx@PtoC
\tx@Shadow
\pst@usecolor\psshadowcolor
gsave fill grestore
stroke
grestore
gsave
\pst@usecolor\psfillcolor
gsave fill grestore
stroke
grestore}}
\def\pst@openshadow{%
\addto@pscode{%
gsave
\psk@shadowsize \psk@shadowangle \tx@PtoC
\tx@Shadow
\pst@usecolor\psshadowcolor
\ifx\psk@fillstyle\relax\else
gsave fill grestore
\fi
stroke}%
\pst@repeatarrows
\addto@pscode{grestore}
\ifx\psk@fillstyle\relax\else
\addto@pscode{%
gsave
\pst@usecolor\psfillcolor
gsave fill grestore
stroke
grestore}
\fi}
\def\pst@addborder{%
\addto@pscode{%
gsave
\psk@border 2 mul
CLW add SLW
\pst@usecolor\psbordercolor
stroke
grestore}}
\def\pst@stroke{%
\ifx\pslinestyle\@none\else
\addto@pscode{%
gsave
\pst@number\pslinewidth SLW
\pst@usecolor\pslinecolor
\@nameuse{psls@\pslinestyle}
grestore}%
\fi}
\def\pst@fill#1{\addto@pscode{gsave #1 grestore}}%
\def\pst@doublestroke{%
\addto@pscode{%
gsave
\psdoublesep SLW
\pst@usecolor\psdoublecolor
stroke
grestore}}
\def\pst@arrowtype{%
\ifx\psk@arrowB\@empty 0 \else -2 \fi
\ifx\psk@arrowA\@empty 0 \else -1 \fi
add}
\def\pst@addarrowdef{%
\addto@pscode{%
/ArrowA {
\ifx\psk@arrowA\@empty
\pst@oplineto
\else
\pst@arrowdef{A}
moveto
\fi
} def
/ArrowB {
\ifx\psk@arrowB\@empty \else \pst@arrowdef{B} \fi
} def}}
\def\pst@arrowdef#1{%
\ifnum\pst@repeatarrowsflag>\z@
/Arrow#1c [ 6 2 roll ] cvx def Arrow#1c
\fi
\tx@BeginArrow
\psk@arrowscale
\@nameuse{psas@\@nameuse{psk@arrow#1}}
\tx@EndArrow}
\def\pst@repeatarrows{%
\addto@pscode{%
gsave
\ifx\psk@arrowA\@empty\else
ArrowAc ArrowA pop pop
\fi
\ifx\psk@arrowB\@empty\else
ArrowBc ArrowB pop pop pop pop
\fi
grestore}}
\def\pst@OpenShowPoints{%
\addto@pscode{%
gsave
\psk@dotsize
\@nameuse{psds@\psk@dotstyle}
newpath
Points aload length 2 div 2 sub cvi /N ED
N 0 ge
{ \ifx\psk@arrowA\@empty
Dot
\else
pop pop
\fi
N { Dot } repeat
\ifx\psk@arrowB\@empty
Dot
\else
pop pop
\fi }
{ N 2 mul { pop } repeat }
ifelse
grestore}}
\def\pscustom{\pst@object{pscustom}}
\long\def\pscustom@i#1{%
\begin@SpecialObj
\solid@star
\let\pst@ifcustom\iftrue
\let\begin@ClosedObj\begin@CustomObj
\let\end@ClosedObj\endgroup
\def\begin@OpenObj{\begin@CustomObj\pst@addarrowdef}%
\let\end@OpenObj\endgroup
\let\begin@AltOpenObj\begin@CustomObj
\def\begin@SpecialObj{%
\begingroup
\pst@misplaced{special graphics object}%
\def\addto@pscode####1{}
\let\end@SpecialObj\endgroup}%
\def\@multips(##1)(##2)##3##4{\pst@misplaced\multips}%
\def\psclip##1{\pst@misplaced\psclip}%
\def\pst@repeatarrowsflag{\z@}%
\let\pst@setrepeatarrowsflag\relax
\showpointsfalse
\let\showpointstrue\relax
\def\pst@linetype{\pslinetype}%
\let\psset@liftpen\psset@@liftpen
\psset@liftpen{\z@}%
\def\pst@cp{/currentpoint load stopped pop }%
\def\pst@oplineto{/lineto load stopped { moveto } if }%
\def\pst@optcp##1##2{%
\ifnum##1=\z@\def##2{/currentpoint load stopped { 0 0 } if }\fi}%
\let\caddto@pscode\addto@pscode
\def\cuse@par##1{{\use@par##1}}%
\the\pst@customdefs
\setbox\pst@hbox=\hbox{#1}%
\psk@fillstyle
\pst@stroke
\end@SpecialObj}
\def\begin@CustomObj{%
\begingroup
\use@par
\addto@pscode{%
\pst@number\pslinewidth SLW
\pst@usecolor\pslinecolor}}
\def\pst@oplineto{moveto }
\def\pst@cp{}
\def\pst@optcp#1#2{}
\def\psset@liftpen#1{}
\def\psset@@liftpen#1{%
\ifcase#1\relax
\def\psk@liftpen{\z@}%
\def\pst@cp{/currentpoint load stopped pop }%
\def\pst@oplineto{/lineto load stopped { moveto } if }%
\or
\def\psk@liftpen{1}%
\def\pst@cp{}%
\def\pst@oplineto{/lineto load stopped { moveto } if }%
\or
\def\psk@liftpen{2}%
\def\pst@cp{}%
\def\pst@oplineto{moveto }%
\fi}
\psset@liftpen{0}
\def\psk@liftpen{-1}
\def\psset@linetype#1{%
\pst@getint{#1}\pslinetype
\ifnum\pst@dimg<-3
\@pstrickserr{linetype must be greater than -3}\@ehpa
\def\pslinetype{0}%
\fi}
\psset@linetype{0}
\def\caddto@pscode#1{%
\@pstrickserr{Command can only be used in \string\pscustom}\@ehpa}
\let\cuse@par\caddto@pscode
\def\tx@MSave{%
/msavemtrx
[ tx@Dict /msavemtrx known { msavemtrx aload pop } if CM ]
def }
\def\tx@MRestore{%
tx@Dict /msavemtrx known { length 0 gt } { false } ifelse
{ /msavematrx [ msavematrx aload pop setmatrix ] def }
if }
\newtoks\pst@customdefs
\pst@customdefs{%
\def\newpath{\addto@pscode{newpath}}%
\def\moveto(#1){\pst@@getcoor{#1}\addto@pscode{\pst@coor moveto}}%
\def\closepath{\addto@pscode{closepath}}%
\def\gsave{\begingroup\addto@pscode{gsave}}%
\def\grestore{\endgroup\addto@pscode{grestore}}%
% DG/SR modification begin - May 12, 1997 - Patch 2
%\def\translate(#1){\pst@@getcoor{#1}\addto@pscode{\pst@coor moveto}}%
\def\translate(#1){\pst@@getcoor{#1}\addto@pscode{\pst@coor translate}}%
% DG/SR modification end
\def\rotate#1{\pst@@getangle{#1}\addto@pscode{\pst@angle rotate}}%
\def\scale#1{\pst@getscale{#1}\pst@tempg\addto@pscode{\pst@tempg}}%
\def\msave{\addto@pscode{\tx@MSave}}%
\def\mrestore{\addto@pscode{\tx@MRestore}}%
\def\swapaxes{\addto@pscode{-90 rotate -1 1 scale}}%
\def\stroke{\pst@object{stroke}}%
\def\fill{\pst@object{fill}}%
\def\openshadow{\pst@object{openshadow}}%
\def\closedshadow{\pst@object{closedshadow}}%
% DG/SR modification begin - Jan. 7, 1998 - Patch 8
%\def\movepath(#1){\pst@@getcoor{#1}\addto@pscode{\pst@coor tx@Shadow}}%
\def\movepath(#1){\pst@@getcoor{#1}\addto@pscode{\pst@coor \tx@Shadow}}%
% DG/SR modification end
\def\lineto{\pst@onecoor{lineto}}%
\def\rlineto{\pst@onecoor{rlineto}}%
\def\curveto{\pst@threecoor{curveto}}%
\def\rcurveto{\pst@threecoor{rcurveto}}%
\def\code#1{\addto@pscode{#1}}%
\def\coor(#1){\pst@@getcoor{#1}\addto@pscode\pst@coor\@ifnextchar({\coor}{}}%
\def\rcoor{\pst@getcoors{}{}}%
\def\dim#1{\pssetlength\pst@dimg{#1}\addto@pscode{\pst@number\pst@dimg}}%
\def\setcolor#1{%
\@ifundefined{color@#1}{}{\addto@pscode{\use@color{#1}}}}%
\def\arrows#1{{\psset@arrows{#1}\pst@addarrowdef}}%
\let\file\pst@rawfile
} % END \pst@customdefs
\def\closedshadow@i{\cuse@par\pst@closedshadow}
\def\openshadow@i{\cuse@par\pst@openshadow}
\def\stroke@i{\cuse@par\pst@stroke}%
\def\fill@i{\cuse@par\psk@fillstyle}%
\def\pst@onecoor#1(#2){%
\pst@@getcoor{#2}%
\addto@pscode{\pst@coor #1}}
\def\pst@threecoor#1(#2)#3(#4)#5(#6){%
\begingroup
\pst@getcoor{#2}\pst@tempa
\pst@getcoor{#4}\pst@tempb
\pst@getcoor{#6}\pst@tembc
\addto@pscode{\pst@tempa \pst@tempb \pst@tempc #1}%
\endgroup}
\def\pst@rawfile#1{%
\begingroup
\def\do##1{\catcode`##1=12\relax}"
\dospecials
\catcode`\%=14
\pst@@rawfile{#1}%
\endgroup}
\def\pst@@rawfile#1{%
\immediate\openin1 #1
\ifeof1
\@pstrickserr{File `#1' not found}\@ehpa
\else
\immediate\read1 to \pst@tempg
\loop
\ifeof1 \@pstfalse\else\@psttrue\fi
\if@pst
\addto@pscode\pst@tempg
\immediate\read1 to \pst@tempg
\repeat
\fi
\immediate\closein1\relax}
\def\tx@NArray{NArray }
\def\tx@NArray{NArray }
\def\tx@Line{Line }
\def\tx@Arcto{Arcto }
\def\tx@CheckClosed{CheckClosed }
\def\tx@Polygon{Polygon }
\def\psset@gangle#1{\pst@getangle{#1}\psk@gangle}
\psset@gangle{0}
\def\tx@Diamond{Diamond }
\def\psdiamond{\pst@object{psdiamond}}
\def\psdiamond@i(#1){%
\@ifnextchar({\psdiamond@ii(#1)}{\psdiamond@ii(0,0)(#1)}}
\def\psdiamond@ii(#1)(#2){%
\begin@ClosedObj
\pst@getcoor{#1}\pst@tempa
\pst@getcoor{#2}\pst@tempb
\addto@pscode{%
\psline@iii
pop
\psk@dimen
\pst@tempb
\psk@gangle
\pst@tempa
\tx@Diamond}%
\def\pst@linetype{4}%
\end@ClosedObj}
\def\tx@Triangle{Triangle }
\def\pstriangle{\pst@object{pstriangle}}
\def\pstriangle@i(#1){%
\@ifnextchar({\pstriangle@ii(#1)}{\pstriangle@ii(0,0)(#1)}}
\def\pstriangle@ii(#1)(#2){%
\begin@ClosedObj
\pst@getcoor{#1}\pst@tempa
\pst@getcoor{#2}\pst@tempb
\addto@pscode{%
\psline@iii
pop
\psk@dimen
\pst@tempb
\psk@gangle
\pst@tempa
\tx@Triangle}%
\def\pst@linetype{2}%
\end@ClosedObj}
\def\tx@CCA{CCA }
\def\tx@CCA{CCA }
\def\tx@CC{CC }
\def\tx@IC{IC }
\def\tx@BOC{BOC }
\def\tx@NC{NC }
\def\tx@EOC{EOC }
\def\tx@BAC{BAC }
\def\tx@NAC{NAC }
\def\tx@EAC{EAC }
\def\tx@OpenCurve{OpenCurve }
\def\tx@AltCurve{AltCurve }
\def\tx@ClosedCurve{ClosedCurve }
\def\psset@curvature#1{%
\edef\pst@tempg{#1 }%
\expandafter\psset@@curvature\pst@tempg * * * \@nil}
\def\psset@@curvature#1 #2 #3 #4\@nil{%
\pst@checknum{#1}\pst@tempg
\pst@checknum{#2}\pst@temph
\pst@checknum{#3}\pst@tempi
\edef\psk@curvature{\pst@tempg \pst@temph \pst@tempi}}
\psset@curvature{1 .1 0}
\def\pscurve{\pst@object{pscurve}}
\def\pscurve@i{%
\pst@getarrows{%
\begin@OpenObj
\pst@getcoors[\pscurve@ii}}
\def\pscurve@ii{%
\addto@pscode{%
\pst@cp
\psk@curvature\space /c ED /b ED /a ED
\ifshowpoints true \else false \fi
\tx@OpenCurve}%
\end@OpenObj}
\def\psecurve{\pst@object{psecurve}}
\def\psecurve@i{%
\pst@getarrows{%
\begin@OpenObj
\pst@getcoors[\psecurve@ii}}
\def\psecurve@ii{%
\addto@pscode{%
\psk@curvature\space /c ED /b ED /a ED
\ifshowpoints true \else false \fi
\tx@AltCurve}%
\end@OpenObj}
\def\psccurve{\pst@object{psccurve}}
\def\psccurve@i{%
\begin@ClosedObj
\pst@getcoors[\psccurve@ii}
\def\psccurve@ii{%
\addto@pscode{%
\psk@curvature\space /c ED /b ED /a ED
\ifshowpoints true \else false \fi
\tx@ClosedCurve}%
\def\pst@linetype{1}%
\end@ClosedObj}
\def\psset@dotsize#1{%
\pst@expandafter\pst@getdimnum{#1} 0 {} {}\@nil
\edef\psk@@dotsize{\pst@number\pst@dimg}%
\let\psk@@@dotsize\pst@tempg
\edef\psk@dotsize{%
/DS \psk@@dotsize \psk@@@dotsize CLW mul add 2 div def }}
\psset@dotsize{2pt 2}
\def\psset@dotscale#1{%
\pst@getscale{#1}\psk@dotscale
\ifx\psk@dotscale\@empty
\def\psk@xdotscale{1 }%
\def\psk@ydotscale{1 }%
\else
\let\psk@xdotscale\pst@tempg
\let\psk@ydotscale\pst@temph
% DG/SR modification begin - Oct. 17, 1997 - Patch 5
%\fi}
\fi
\pst@getdotsize%
\psset@dotsize{\pst@dimg\space\pst@@dimtonum\pst@dimh}}
%\psset@dotscale{1}
% DG/SR modification end
\def\pst@Getangle#1#2{%
\pst@getangle{#1}\pst@tempg
\def\pst@temph{0. }%
\ifx\pst@tempg\pst@temph
\def#2{}%
\else
\edef#2{\pst@tempg\space rotate }%
\fi}
\def\psset@dotangle#1{%
\pst@getangle{#1}\psk@@dotangle
\ifdim\psk@@dotangle\p@=\z@
\let\psk@dotangle\@empty
\else
% DG/SR modification begin - Aug. 8, 1997 - Patch 4
%\edef\psk@dotangle{\psk@@dotangle rotate }
\edef\psk@dotangle{\psk@@dotangle rotate }%
% DG/SR modification end
\fi}
\psset@dotangle{0}
\def\pst@getdotsize{%
\pst@dimg=\psk@@@dotsize\pslinewidth
\advance\pst@dimg\psk@@dotsize\p@
\pst@dimh=\psk@ydotscale\pst@dimg
\pst@dimg=\psk@xdotscale\pst@dimg
\divide\pst@dimh 2
\divide\pst@dimg 2\relax}
% DG/SR modification begin - Oct. 17, 1997 - Patch 5
\psset@dotscale{1}
% DG/SR modification end
\def\psdot{\pst@object{psdot}}
\def\psdot@i{\@ifnextchar({\psdot@ii}{\psdot@ii(\z@,\z@)}}
\def\psdot@ii(#1){%
\begin@SpecialObj
\pst@@getcoor{#1}%
\addto@pscode{%
\psk@dotsize
\@nameuse{psds@\psk@dotstyle}%
\pst@coor Dot}%
\end@SpecialObj}
\def\psdots{\pst@object{psdots}}
\def\psdots@i{%
\begin@SpecialObj
\pst@getcoors[\psdots@ii}
\def\psdots@ii{%
\addto@pscode{false \tx@NArray \psdots@iii}%
\end@SpecialObj}
\def\psdots@iii{%
\psk@dotsize
\@nameuse{psds@\psk@dotstyle}
newpath
n { transform floor .5 add exch floor .5 add exch itransform Dot } repeat}
% DG: dead code (to suppress until \psset@dotstyle) ? - Aug. 4, 1997
\def\tx@SQ{SQ }
\def\tx@ST{ST }
\def\tx@SP{SP }
\def\pst@gdot#1{/Dot { gsave T \psk@dotangle \psk@dotscale #1 grestore } def }
\@namedef{psds@*}{\pst@gdot{0 0 DS \tx@SD}}
\@namedef{psds@o}{%
/r2 DS CLW sub def
\pst@gdot{0 0 DS \tx@SD \pst@usecolor\psfillcolor 0 0 r2 \tx@SD}}
\@namedef{psds@square*}{%
/r1 DS .886 mul def
\pst@gdot{r1 \tx@SQ}}
\@namedef{psds@square}{%
/r1 DS .886 mul def /r2 r1 CLW sub def
\pst@gdot{r1 \tx@SQ \pst@usecolor\psfillcolor r2 \tx@SQ}}
\@namedef{psds@triangle*}{%
/y1 DS .778 mul neg def /x1 y1 1.732 mul neg def
\pst@gdot{x1 y1 \tx@ST}}
\@namedef{psds@triangle}{%
/y1 DS .778 mul neg def /x1 y1 1.732 mul neg def
/y2 y1 CLW add def /x2 y2 1.732 mul neg def
\pst@gdot{x1 y1 \tx@ST \pst@usecolor\psfillcolor x2 y2 \tx@ST}}
\@namedef{psds@pentagon*}{%
/r1 DS 1.149 mul def
\pst@gdot{r1 \tx@SP}}
\@namedef{psds@pentagon}{%
DS .93 mul dup 1.236 mul /r1 ED CLW sub 1.236 mul /r2 ED
\pst@gdot{r1 \tx@SP \pst@usecolor\psfillcolor r2 \tx@SP}}
\@namedef{psds@+}{%
/DS DS 1.253 mul def
\pst@gdot{DS 0 moveto DS neg 0 L stroke 0 DS moveto 0 DS neg L stroke}}
\@namedef{psds@|}{%
\psk@tbarsize CLW mul add 2 div /DS ED
\pst@gdot{0 DS moveto 0 DS neg L stroke}}
% DG: end dead code?
\def\psset@dotstyle#1{%
\@ifundefined{psds@#1}%
{\@pstrickserr{Dot style `#1' not defined}\@eha}%
{\edef\psk@dotstyle{#1}}}
\psset@dotstyle{*}
\def\tx@FontDot{FontDot }
\def\newpsfontdot#1[#2]#3#4{%
\@namedef{psds@#1}{%
/#3 \psk@@dotangle [#2] \tx@FontDot
/Dot { moveto #4 show } bind def }}
\def\newpsfontdotH#1[#2]#3#4#5{%
\@namedef{psds@#1}{%
/#3 \psk@@dotangle [#2] \tx@FontDot
/Dot {
moveto
\iftrue
gsave \pst@usecolor\psfillcolor #5 show grestore
\fi
#4 show
} bind def }}
\pstheader{pst-dots.pro}
\newpsfontdot{*}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(b)}
\newpsfontdotH{o}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(c)}{(b)}
\newpsfontdotH{Bo}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(C)}{(b)}
\newpsfontdotH{triangle}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(t)}{(u)}
\newpsfontdotH{Btriangle}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(T)}{(u)}
\newpsfontdot{triangle*}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(u)}
\newpsfontdotH{square}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(s)}{(r)}
\newpsfontdotH{Bsquare}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(S)}{(r)}
\newpsfontdot{square*}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(r)}
\newpsfontdotH{pentagon}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(p)}{(q)}
\newpsfontdotH{Bpentagon}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(P)}{(q)}
\newpsfontdot{pentagon*}%
[1.0 0.0 0.0 1.0 0.0 0.0]{PSTricksDotFont}{(q)}
% DG/SR modification begin - Mar. 18, 1997
%\newpsfontdot{diamond*}%
%[1.9 0.0 0.0 1.9 -0.4598 -0.70775]{Symbol}{<E0>}
%\newpsfontdot{diamond}%
%[2.3 0.0 0.0 2.3 -0.8533 -0.5336]{Symbol}{<A8>}
\newpsfontdot{diamond}%
[1.9 0.0 0.0 1.9 -0.4598 -0.70775]{Symbol}{<E0>}
\newpsfontdot{diamond*}%
[2.3 0.0 0.0 2.3 -0.8533 -0.5336]{Symbol}{<A8>}
% DG/SR modification end
\newpsfontdot{oplus}%
[1.44928 0.0 0.0 1.44928 -0.562319 -0.478261]{Symbol}{<C5>}
\newpsfontdot{otimes}%
[1.44928 0.0 0.0 1.44928 -0.562319 -0.475362]{Symbol}{<C4>}
\newpsfontdot{x}%
[1.8 0.0 0.0 1.8 -0.495 -0.4788]{Symbol}{<B4>}
\newpsfontdot{+}%
[2.3 0.0 0.0 2.3 -0.6486 -0.5819]{Times-Roman}{<2B>}
\newpsfontdot{asterisk}%
[2.43309 0.0 0.0 2.43309 -0.609489 -1.14477]{Times-Roman}{<2A>}
\newpsfontdot{B+}%
[2.3 0.0 0.0 2.3 -0.6555 -0.5819]{Times-Bold}{<2B>}
\newpsfontdot{Basterisk}%
[2.29358 0.0 0.0 2.29358 -0.576835 -1.08486]{Times-Bold}{<2A>}
\newpsfontdot{|}%
% DG/SR modification begin - Oct. 27, 1997 - Patch 7
%[1.98413 0.0 0.0 1.98413 -0.258929 -0.712302]{Helvetica}{(|)}
[1.98413 0.0 0.0 1.38 -0.258929 -0.5]{Helvetica}{(|)}
% DG/SR modification end
\newpsfontdot{B|}%
% DG/SR modification begin - Oct. 27, 1997 - Patch 7
%[1.98413 0.0 0.0 1.98413 -0.277778 -0.78302]{Helvetica-Bold}{(|)}
[1.98413 0.0 0.0 1.38 -0.277778 -0.5]{Helvetica-Bold}{(|)}
% DG/SR modification end
\iffalse
\newpsfontdot{*}%
[2.77778 0.0 0.0 2.77778 -0.638889 -0.813889]{Symbol}{<B7>}
\newpsfontdot{o}%
[3.33333 0.0 0.0 3.33333 -0.666667 -1.78167]{Symbol}{<B0>}
\newpsfontdot{Bo}%
[4.69484 0.0 0.0 4.69484 -0.78169 -2.97418]{Times-Bold}{<CA>}
\fi
\newdimen\pslinearc
\def\psset@linearc#1{\pssetlength\pslinearc{#1}}
\psset@linearc{0pt}
\def\psline{\pst@object{psline}}
\def\psline@i{%
\pst@getarrows{%
\begin@OpenObj
\pst@getcoors[\psline@ii}}
\def\psline@ii{%
\addto@pscode{\pst@cp \psline@iii \tx@Line}%
\end@OpenObj}
\def\psline@iii{%
\ifdim\pslinearc>\z@
/r \pst@number\pslinearc def
/Lineto { \tx@Arcto } def
\else
/Lineto /lineto load def
\fi
\ifshowpoints true \else false \fi}
\def\qline(#1)(#2){%
\def\pst@par{}%
\begin@SpecialObj
\def\pst@linetype{0}%
\pst@getcoor{#1}\pst@tempa
\pst@@getcoor{#2}%
\addto@pscode{%
\pst@tempa moveto \pst@coor L
\@nameuse{psls@\pslinestyle}}%
\end@SpecialObj}
\def\pspolygon{\pst@object{pspolygon}}
\def\pspolygon@i{%
\begin@ClosedObj
\def\pst@cp{}%
\pst@getcoors[\pspolygon@ii}
\def\pspolygon@ii{%
\addto@pscode{\psline@iii \tx@Polygon}%
\def\pst@linetype{1}%
\end@ClosedObj}
\def\psset@framearc#1{\pst@checknum{#1}\psk@framearc}
\psset@framearc{0}
\def\psset@cornersize#1{%
\pst@expandafter\psset@@cornersize{#1}\@nil}
\def\psset@@cornersize#1#2\@nil{%
\if #1a\relax
\def\psk@cornersize{\pst@number\pslinearc false }%
\else
\def\psk@cornersize{\psk@framearc true }%
\fi}
\psset@cornersize{relative}
\def\tx@Rect{Rect }
\def\tx@OvalFrame{OvalFrame }
\def\tx@Frame{Frame }
\def\psset@dimen#1{%
\pst@expandafter\psset@@dimen{#1}\@nil}
\def\psset@@dimen#1#2\@nil{%
\if #1o\relax
\def\psk@dimen{.5 }%
\else
\if #1m\relax
\def\psk@dimen{0 }%
\else
\if #1i\relax
\def\psk@dimen{-.5 }%
\fi
\fi
\fi}
\psset@dimen{outer}
\def\psframe{\pst@object{psframe}}
\def\psframe@i(#1){%
\@ifnextchar({\psframe@ii(#1)}{\psframe@ii(0,0)(#1)}}
\def\psframe@ii(#1)(#2){%
\begin@ClosedObj
\pst@getcoor{#1}\pst@tempa
\pst@@getcoor{#2}%
\addto@pscode{\psk@cornersize \pst@tempa \pst@coor \psk@dimen \tx@Frame}%
\def\pst@linetype{2}%
\showpointsfalse
\end@ClosedObj}
\def\tx@BezierNArray{BezierNArray }
\def\tx@OpenBezier{OpenBezier }
\def\tx@ClosedBezier{ClosedBezier }
\def\tx@BezierShowPoints{BezierShowPoints }
\def\psbezier{\pst@object{psbezier}}
\def\psbezier@i{%
\pst@getarrows{%
\begin@OpenObj
\pst@getcoors[\psbezier@ii}}
\def\psbezier@ii{%
\addto@pscode{%
% DG/SR modification begin - Apr. 28, 1997 - Patch 1
% \psbezier doesn't work inside \pscustom
%\pst@cp
% DG/SR modification end
\ifshowpoints true \else false \fi
\tx@OpenBezier
\ifshowpoints \tx@BezierShowPoints \fi}%
\end@OpenObj}
\def\pscbezier{\pst@object{pscbezier}}
\def\pscbezier@i{%
\begin@ClosedObj
\pst@getcoors[\pscbezier@ii}
\def\pscbezier@ii{%
\addto@pscode{%
\ifshowpoints true \else false \fi
\tx@ClosedBezier
\ifshowpoints \tx@BezierShowPoints \fi}%
\chardef\pst@linetype=1
\end@ClosedObj}
\def\tx@Parab{Parab }
\def\parabola{\pst@object{parabola}}
\def\parabola@i{\pst@getarrows\parabola@ii}
\def\parabola@ii#1(#2)#3(#4){%
\begin@OpenObj
\pst@getcoor{#2}\pst@tempa
\pst@@getcoor{#4}%
\addto@pscode{\pst@tempa \pst@coor \tx@Parab}%
\end@OpenObj}
\def\psset@gridwidth#1{\pst@getlength{#1}\psk@gridwidth}
\psset@gridwidth{.8pt}
\def\psset@griddots#1{%
\pst@cntg=#1\relax
\edef\psk@griddots{\the\pst@cntg}}
\psset@griddots{0}
\def\psset@gridcolor#1{\pst@getcolor{#1}\psgridcolor}
\psset@gridcolor{black}
\def\psset@subgridwidth#1{\pst@getlength{#1}\psk@subgridwidth}
\psset@subgridwidth{.4pt}
\def\psset@subgridcolor#1{\pst@getcolor{#1}\pssubgridcolor}
\psset@subgridcolor{gray}
\def\psset@subgriddots#1{%
\pst@cntg=#1\relax\edef\psk@subgriddots{\the\pst@cntg}}
\psset@subgriddots{0}
\def\psset@subgriddiv#1{%
\pst@cntg=#1\relax\edef\psk@subgriddiv{\the\pst@cntg}}
\psset@subgriddiv{5}
\def\psset@gridlabels#1{\pst@getlength{#1}\psk@gridlabels}
\psset@gridlabels{10pt}
\def\psset@gridlabelcolor#1{\pst@getcolor{#1}\psgridlabelcolor}
\psset@gridlabelcolor{black}
\def\tx@Grid{Grid }
\def\psgrid{\pst@object{psgrid}}
\def\psgrid@i{\@ifnextchar(%
{\psgrid@ii}{\expandafter\psgrid@iv\pic@coor}}
\def\psgrid@ii(#1){\@ifnextchar(%
{\psgrid@iii(#1)}{\psgrid@iv(0,0)(0,0)(#1)}}
\def\psgrid@iii(#1)(#2){\@ifnextchar(%
{\psgrid@iv(#1)(#2)}{\psgrid@iv(#1)(#1)(#2)}}
\def\psgrid@iv(#1)(#2)(#3){%
\begin@SpecialObj
\pst@getcoor{#1}\pst@tempa
\pst@getcoor{#2}\pst@tempb
\pst@@getcoor{#3}%
\ifnum\psk@subgriddiv>1
\addto@pscode{gsave
\psk@subgridwidth SLW \pst@usecolor\pssubgridcolor
\pst@tempb \pst@coor \pst@tempa
\pst@number\psxunit \pst@number\psyunit
\psk@subgriddiv\space \psk@subgriddots\space
{} 0 \tx@Grid grestore}%
\fi
\addto@pscode{gsave
\psk@gridwidth SLW \pst@usecolor\psgridcolor
\pst@tempb \pst@coor \pst@tempa
\pst@number\psxunit \pst@number\psyunit
1 \psk@griddots\space { \pst@usecolor\psgridlabelcolor }
\psk@gridlabels \tx@Grid grestore}%
\end@SpecialObj}
\newif\ifpsmathbox
\psmathboxtrue
\def\pst@mathflag{\z@}
\newtoks\everypsbox
\let\pst@thisbox\relax
\long\def\pst@makenotverbbox#1#2{%
\edef\pst@mathflag{%
\ifpsmathbox\ifmmode\ifinner 1\else 2\fi\else \z@\fi\else \z@\fi}%
\setbox\pst@hbox=\hbox{%
\ifcase\pst@mathflag\or$\m@th\textstyle\or$\m@th\displaystyle\fi
{\pst@thisbox\the\everypsbox#2}%
\ifnum\pst@mathflag>\z@$\fi}%
#1}
\def\pst@makeverbbox#1{%
\def\pst@afterbox{#1}%
\edef\pst@mathflag{%
\ifpsmathbox\ifmmode\ifinner 1\else 2\fi\else \z@\fi\else \z@\fi}%
\afterassignment\pst@beginbox
\setbox\pst@hbox\hbox}
\def\pst@beginbox{%
\ifcase\pst@mathflag\or$\m@th\or$\m@th\displaystyle\fi
\bgroup\aftergroup\pst@endbox
\pst@thisbox
\the\everypsbox}
\def\pst@endbox{%
\ifnum\pst@mathflag>\z@$\fi
\egroup
\pst@afterbox}
\def\pst@makebox{\pst@@makebox}
\def\psverbboxtrue{\def\pst@@makebox{\pst@makeverbbox}}
\def\psverbboxfalse{\def\pst@@makebox{\pst@makenotverbbox}}
\psverbboxfalse
\def\pst@longbox{%
\def\pst@makebox{%
\gdef\pst@makebox{\pst@@makebox}%
\pst@makelongbox}}
\def\pst@makelongbox#1{%
\def\pst@afterbox{#1}%
\edef\pst@mathflag{%
\ifpsmathbox\ifmmode\ifinner 1\else 2\fi\else \z@\fi\else \z@\fi}%
\setbox\pst@hbox\hbox\bgroup
\aftergroup\pst@afterbox
\ifcase\pst@mathflag\or$\m@th\or$\m@th\displaystyle\fi
\begingroup
\pst@thisbox
\the\everypsbox}
\def\pst@endlongbox{%
\endgroup
\ifnum\pst@mathflag>\z@$\fi
\egroup}
\def\pslongbox#1#2{%
\@namedef{#1}{\pst@longbox#2}%
\@namedef{end#1}{\pst@endlongbox}}
\newdimen\psframesep
\def\psset@framesep#1{\pssetlength\psframesep{#1}}
\psset@framesep{3pt}
\newif\ifpsboxsep
\def\psset@boxsep#1{\@nameuse{psboxsep#1}}
\psset@boxsep{true}
\def\pst@useboxpar{%
\use@par
\if@star
\let\pslinecolor\psfillcolor
\solid@star
\let\solid@star\relax
\fi
\ifpsdoubleline \pst@setdoublesep \fi}
\def\psframebox{\pst@object{psframebox}}
\def\psframebox@i{\pst@makebox\psframebox@ii}
\def\psframebox@ii{%
\begingroup
\pst@useboxpar
\pst@dima=\pslinewidth
\advance\pst@dima by \psframesep
\pst@dimc=\wd\pst@hbox\advance\pst@dimc by \pst@dima
\pst@dimb=\dp\pst@hbox\advance\pst@dimb by \pst@dima
\pst@dimd=\ht\pst@hbox\advance\pst@dimd by \pst@dima
\setbox\pst@hbox=\hbox{%
\ifpsboxsep\kern\pst@dima\fi
\begin@ClosedObj
\addto@pscode{%
\psk@cornersize
\pst@number\pst@dima neg
\pst@number\pst@dimb neg
\pst@number\pst@dimc
\pst@number\pst@dimd
.5
\tx@Frame}%
\def\pst@linetype{2}%
\showpointsfalse
\end@ClosedObj
\box\pst@hbox
\ifpsboxsep\kern\pst@dima\fi}%
\ifpsboxsep\dp\pst@hbox=\pst@dimb\ht\pst@hbox=\pst@dimd\fi
\leavevmode\box\pst@hbox
\endgroup}
\def\psdblframebox{\pst@object{psdblframebox}}
\def\psdblframebox@i{\addto@par{doubleline=true}\psframebox@i}
\def\psclip#1{%
\leavevmode
\begingroup
\begin@psclip
\begingroup
\def\use@pscode{%
\pstVerb{%
\pst@dict
/mtrxc CM def
CP CP T
\tx@STV
\psk@origin
\psk@swapaxes
newpath
\pst@code
clip
newpath
mtrxc setmatrix
moveto
0 setgray
end}%
\gdef\pst@code{}}%
\def\@multips(##1)(##2)##3##4{\pst@misplaced\multips}%
\def\nc@object##1##2##3##4{\pst@misplaced{node connection}}%
\hbox to\z@{#1}%
\endgroup
\def\endpsclip{%
\end@psclip
\endgroup}%
\ignorespaces}
\def\endpsclip{\pst@misplaced\endpsclip}
\let\begin@psclip\relax
\def\end@psclip{\pstVerb{currentpoint initclip moveto}}
\def\AltClipMode{%
\def\end@psclip{\pstVerb{\pst@grestore}}%
\def\begin@psclip{\pstVerb{gsave}}}
\def\clipbox{\@ifnextchar[{\clipbox@}{\clipbox@[\z@]}}
% DG modification begin - Apr. 3, 1997
% From paulus@immd5.informatik.uni-erlangen.de (Dietrich Paulus)
%\def\clipbox@[#1]{\pst@makebox\clipbox@@{#1}}
\def\clipbox@[#1]{\pst@makebox{\clipbox@@{#1}}}
% DG modification end
\def\clipbox@@#1{%
\pssetlength\pst@dimg{#1}%
\leavevmode\hbox{%
\begin@psclip
\pst@Verb{%
CM \tx@STV CP T newpath
/a \pst@number\pst@dimg def
/w \pst@number{\wd\pst@hbox}a add def
/d \pst@number{\dp\pst@hbox}a add neg def
/h \pst@number{\ht\pst@hbox}a add def
a neg d moveto
a neg h L
w h L
w d L
closepath
clip
newpath
0 0 moveto
setmatrix}%
\unhbox\pst@hbox
\end@psclip}}
\def\psshadowbox{\pst@object{psshadowbox}}
\def\psshadowbox@i{\pst@makebox\psshadowbox@ii}
\def\psshadowbox@ii{%
\begingroup
\pst@useboxpar
\psshadowtrue
\psboxseptrue
\def\psk@shadowangle{-45 }%
\setbox\pst@hbox=\hbox{\psframebox@ii}%
\pst@dimh=\psk@shadowsize\p@
\pst@dimh=.7071\pst@dimh
\pst@dimg=\dp\pst@hbox
\advance\pst@dimg\pst@dimh
\dp\pst@hbox=\pst@dimg
\pst@dimg=\wd\pst@hbox
\advance\pst@dimg\pst@dimh
\wd\pst@hbox=\pst@dimg
\leavevmode
\box\pst@hbox
\endgroup}
\def\pscirclebox{\pst@object{pscirclebox}}
\def\pscirclebox@i{\pst@makebox\pscirclebox@ii}
\def\pscirclebox@ii{%
\begingroup
\pst@useboxpar
\setbox\pst@hbox=\hbox{%
\pst@nodehook
\pscirclebox@iii
\box\pst@hbox}%
\ifpsboxsep \pscirclebox@sep \fi
\leavevmode
\box\pst@hbox
\endgroup}
\def\pscirclebox@iii{%
\if@star
\pslinewidth\z@
\pstverb{\pst@dict \tx@STP \pst@usecolor\psfillcolor
newpath \pscirclebox@iv \tx@SD end}%
\else
\begin@ClosedObj
\def\pst@linetype{4}\showpointsfalse
\addto@pscode{%
\pscirclebox@iv CLW 2 div add 0 360 arc closepath}%
\end@ClosedObj
\fi}
\def\pscirclebox@iv{%
\pst@number{\wd\pst@hbox}2 div
\pst@number{\ht\pst@hbox}\pst@number{\dp\pst@hbox}add 2 div
2 copy \pst@number{\dp\pst@hbox}sub 4 2 roll
\tx@Pyth \pst@number\psframesep add }
\def\pscirclebox@sep{%
\pst@dimb=\ht\pst@hbox
\advance\pst@dimb\dp\pst@hbox
\divide\pst@dimb 2
\pst@dima=.5\wd\pst@hbox
\pst@pyth\pst@dima\pst@dimb\pst@dimc
\advance\pst@dimc\pslinewidth
\advance\pst@dimc\psframesep
\advance\pst@dimb-\pst@dimc
\setbox\pst@hbox=\hbox to2\pst@dimc{%
\hss
\vbox{\kern-\pst@dimb\box\pst@hbox}%
\hss}%
\advance\pst@dimb-\dp\pst@hbox
\dp\pst@hbox=-\pst@dimb}
\let\pst@nodehook\relax
\def\psCirclebox{\pst@object{psCirclebox}}
\def\psCirclebox@i{\pst@makebox\psCirclebox@ii}
\def\psCirclebox@ii{%
\begingroup
\pst@useboxpar
\pst@dima=\ht\pst@hbox
\advance\pst@dima\dp\pst@hbox
\divide\pst@dima\tw@
\pssetlength\pst@dimb\psk@radius
\setbox\pst@hbox=\hbox{%
\pst@nodehook
\pscircle(.5\wd\pst@hbox,\pst@dima){\pst@dimb}%
\box\pst@hbox}%
\ifpsboxsep \psCirclebox@sep \fi
\leavevmode
\box\pst@hbox
\endgroup}
\def\psCirclebox@sep{%
\pst@dimc=\pst@dimb
\advance\pst@dimb-\pst@dima
\advance\pst@dima\pst@dimc
\setbox\pst@hbox=\hbox to\tw@\pst@dimc{%
\hss
\vrule width \z@ depth \pst@dimb height \pst@dima
\box\pst@hbox
\hss}}%
\def\psovalbox{\pst@object{psovalbox}}
\def\psovalbox@i{\pst@makebox{\psovalbox@ii}}
\def\psovalbox@ii{%
\begingroup
\pst@useboxpar
\psovalbox@iii
\ifpsboxsep\psovalbox@sep\fi
\leavevmode
\box\pst@hbox
\endgroup}
\def\psovalbox@iii{%
\psovalbox@iv
\setbox\pst@hbox=\hbox{%
\begin@ClosedObj
\addto@pscode{%
0 360
\pst@number\pst@dimc CLW 2 div sub
\pst@number\pst@dimd CLW 2 div sub
\pst@number\pst@dima
\pst@number\pst@dimb
\tx@Ellipse
closepath}%
\def\pst@linetype{2}%
\end@ClosedObj
\unhbox\pst@hbox}}
\def\psovalbox@iv{%
\pst@dimc=\pslinewidth\advance\pst@dimc\psframesep
\pst@dimd=\ht\pst@hbox\advance\pst@dimd\dp\pst@hbox
\pst@dima=.5\wd\pst@hbox
\pst@dimb=.5\pst@dimd\advance\pst@dimb-\dp\pst@hbox
\pst@dimd=.707\pst@dimd
\advance\pst@dimd\pst@dimc
\advance\pst@dimc.707\wd\pst@hbox}
\def\psovalbox@sep{%
\setbox\pst@hbox\hbox to 2\pst@dimc{\hss\unhbox\pst@hbox\hss}%
\pst@dimg=\pst@dimd
\advance\pst@dimg-\pst@dimb
\dp\pst@hbox=\pst@dimg
\advance\pst@dimd\pst@dimb
\ht\pst@hbox=\pst@dimd}
\def\psdiabox{\pst@object{psdiabox}}
\def\psdiabox@i{\pst@makebox{\psdiabox@ii}}
\def\psdiabox@ii{%
\begingroup
\pst@useboxpar
\psdiabox@iii
\ifpsboxsep\psdiabox@sep\fi
\leavevmode
\box\pst@hbox
\endgroup}
\def\psdiabox@iv{%
\pst@dimg=.707\pslinewidth
\advance\pst@dimg.707\psframesep
\pst@dima=\wd\pst@hbox
\divide\pst@dima 2
\pst@dimc=\pst@dima
\advance\pst@dimc\pst@dimg
\pst@dimd=\ht\pst@hbox
\advance\pst@dimd\dp\pst@hbox
\divide\pst@dimd 2
\pst@dimb=\pst@dimd
\advance\pst@dimb-\dp\pst@hbox
\advance\pst@dimd\pst@dimg}
\def\psdiabox@iii{%
\psdiabox@iv
\setbox\pst@hbox=\hbox{%
\begin@ClosedObj
\addto@pscode{%
\psline@iii
pop
.5
\pst@number\pst@dimc 2 mul \pst@number\pst@dimd 2 mul
0
\pst@number\pst@dima \pst@number\pst@dimb
\tx@Diamond}%
\def\pst@linetype{4}%
\end@ClosedObj
\box\pst@hbox}}
\def\psdiabox@sep{%
\setbox\pst@hbox\hbox to 4\pst@dimc{\hss\unhbox\pst@hbox\hss}%
\multiply\pst@dimd 2
\advance\pst@dimd\pst@dimb
\ht\pst@hbox\pst@dimd
\advance\pst@dimd-2\pst@dimb
\dp\pst@hbox\pst@dimd}
\def\psset@trimode#1{\pst@expandafter\psset@@trimode{#1}\@empty\@empty\@nil}
\def\psset@@trimode#1#2#3\@nil{%
\let\pst@tempg#1\relax
\ifx\pst@tempg*%
\let\psk@@trimode\@empty
\let\pst@tempg#2\relax
\else
\let\psk@@trimode\relax
\fi
\edef\psk@trimode{%
\ifx R\pst@tempg 1 \else\ifx D\pst@tempg 2
\else\ifx L\pst@tempg 3 \else 0 \fi\fi\fi}}
\psset@trimode{U}
\def\pstribox{\pst@object{pstribox}}
\def\pstribox@i{\pst@makebox{\pstribox@ii}}
\def\pstribox@ii{%
\begingroup
\pst@useboxpar
\pstribox@iii
\ifpsboxsep\pstribox@sep\fi
\leavevmode
\box\pst@hbox
\endgroup}
\def\pstribox@iii{%
\pstribox@iv
\setbox\pst@hbox=\hbox{%
\begin@ClosedObj
\addto@pscode{%
\psline@iii
pop
.5
\pst@number\pst@dimc \pst@number\pst@dimd
\ifodd\psk@trimode exch \fi
\psk@trimode -90 mul
\pst@number\pst@dima \pst@number\pst@dimb
\tx@Triangle}%
\def\pst@linetype{2}%
\end@ClosedObj
\box\pst@hbox}}
\def\pstribox@iv{%
\pst@dimh=\pslinewidth
\advance\pst@dimh\psframesep
\pst@dimg=\ht\pst@hbox
\advance\pst@dimg-\dp\pst@hbox
\divide\pst@dimg 2
\edef\pst@tempa{\number\pst@dimg sp}% For use by nodes.
\ifodd\psk@trimode
\pst@dimb\pst@dimg
\else
\pst@dima=\wd\pst@hbox
\divide\pst@dima 2
\fi
\ifcase\psk@trimode
\pst@dimb=-\dp\pst@hbox
\advance\pst@dimb-\pst@dimh
\or
\pst@dima=-\pst@dimh
\or
\pst@dimb=\ht\pst@hbox
\advance\pst@dimb\pst@dimh
\or
\pst@dima=\wd\pst@hbox
\advance\pst@dima\pst@dimh
\fi
\pst@dimd=\dp\pst@hbox
\advance\pst@dimd\ht\pst@hbox
\ifx\psk@@trimode\relax
\pst@dimc=\wd\pst@hbox
\advance\pst@dimc\ifodd\psk@trimode 1.447\else 1.789\fi\pst@dimh
\multiply\pst@dimc 2
\advance\pst@dimd\ifodd\psk@trimode 1.789\else 1.447\fi\pst@dimh
\multiply\pst@dimd 2
\else
\ifodd\psk@trimode
\advance\pst@dimd 1.1547\wd\pst@hbox
\advance\pst@dimd 3.4641\pst@dimh
\pst@dimc=.866\pst@dimd
\else
\advance\pst@dimd .866\wd\pst@hbox %.866=(sqrt(3)/2)
\advance\pst@dimd 3\pst@dimh
\pst@dimc=1.1547\pst@dimd % 1.1547=(2/sqrt(3))
\fi
\fi}
\def\pstribox@sep{%
\ifodd\psk@trimode
\advance\pst@dimb.5\pst@dimd
\ht\pst@hbox=\pst@dimb
\advance\pst@dimd-\pst@dimb
\dp\pst@hbox=\pst@dimd
\else
\setbox\pst@hbox\hbox to \pst@dimc{\hss\unhbox\pst@hbox\hss}%
\global\pst@dimg=.5\pst@dimc
\fi
\ifcase\psk@trimode
\dp\pst@hbox-\pst@dimb
\advance\pst@dimd\pst@dimb
\ht\pst@hbox\pst@dimd
\or
\pst@dimg=.5\wd\pst@hbox
\global\advance\pst@dimg-\pst@dima
\setbox\pst@hbox\hbox to \pst@dimc{\kern-\pst@dima\box\pst@hbox\hss}%
\or
\ht\pst@hbox\pst@dimb
\advance\pst@dimd-\pst@dimb
\dp\pst@hbox\pst@dimd
\or
\pst@dimg=\pst@dimc
\advance\pst@dimg-\pst@dima
\global\advance\pst@dimg.5\wd\pst@hbox
\setbox\pst@hbox\hbox to \pst@dimc{%
\hss\box\pst@hbox\kern\psframesep\kern\pslinewidth}%
\fi}
\def\psset@arcsepA#1{\pst@getlength{#1}\psk@arcsepA}
\def\psset@arcsepB#1{\pst@getlength{#1}\psk@arcsepB}
\def\psset@arcsep#1{%
\psset@arcsepA{#1}\let\psk@arcsepB\psk@arcsepA}
\psset@arcsep{0}
\def\tx@ArcArrow{ArcArrow }
\def\psarc{\pst@object{psarc}}
\def\psarc@i{%
\@ifnextchar({\psarc@iii}{\psarc@ii}}
\def\psarc@ii#1{\addto@par{arrows=#1}%
\@ifnextchar({\psarc@iii}{\psarc@iii(0,0)}}
\def\psarc@iii(#1)#2#3#4{%
\begin@OpenObj
\pst@getangle{#3}\pst@tempa
\pst@getangle{#4}\pst@tempb
\pst@@getcoor{#1}%
\pssetlength\pst@dima{#2}%
\addto@pscode{\psarc@iv \psarc@v}%
\gdef\psarc@type{0}%
\showpointsfalse
\end@OpenObj}
\def\psarc@iv{%
\pst@coor /y ED /x ED
/r \pst@number\pst@dima def
/c 57.2957 r \tx@Div def
/angleA
\pst@tempa
\psk@arcsepA c mul 2 div
\ifcase \psarc@type add \or sub \fi
def
/angleB
\pst@tempb
\psk@arcsepB c mul 2 div
\ifcase \psarc@type sub \or add \fi
def
\ifshowpoints\psarc@showpoints\fi
\ifx\psk@arrowA\@empty
\ifnum\psk@liftpen=2
r angleA \tx@PtoC
y add exch x add exch
moveto
\fi
\fi}
\def\psarc@v{%
x y r
angleA
\ifx\psk@arrowA\@empty\else
{ ArrowA CP }
{ \ifcase\psarc@type add \or sub \fi }
\tx@ArcArrow
\fi
angleB
\ifx\psk@arrowB\@empty\else
{ ArrowB }
{ \ifcase\psarc@type sub \or add \fi }
\tx@ArcArrow
\fi
\ifcase\psarc@type arc \or arcn \fi}
\def\psarc@type{0}
\def\psarc@showpoints{%
gsave
newpath
x y moveto
x y r \pst@tempa \pst@tempb
\ifcase\psarc@type arc \or arcn \fi
closepath
CLW 2 div SLW
[ \psk@dash\space ] 0 setdash stroke
grestore }
\def\psarcn{\pst@object{psarcn}}
\def\psarcn@i{\def\psarc@type{1}\psarc@i}
\def\pscircle{\pst@object{pscircle}}
\def\pscircle@i{\@ifnextchar({\pscircle@do}{\pscircle@do(0,0)}}
\def\pscircle@do(#1)#2{%
\if@star
{\use@par\qdisk(#1){#2}}%
\else
\begin@ClosedObj
\pst@@getcoor{#1}%
\pssetlength\pst@dimc{#2}%
\def\pst@linetype{4}%
\addto@pscode{%
\pst@coor
\pst@number\pst@dimc
\psk@dimen CLW mul sub
0 360 arc
closepath}%
\showpointsfalse
\end@ClosedObj
\fi
\ignorespaces}
\def\qdisk(#1)#2{%
\def\pst@par{}%
\begin@SpecialObj
\pst@@getcoor{#1}%
\pssetlength\pst@dimg{#2}%
\addto@pscode{\pst@coor \pst@number\pst@dimg \tx@SD}%
\end@SpecialObj}
\def\psset@radius#1{\pst@@getlength{#1}\psk@radius}
\psset@radius{.25cm}
\def\psCircle{\pst@object{psCircle}}
\def\psCircle@i{\@ifnextchar({\psCircle@ii}{\psCircle@ii(0,0)}}
\def\psCircle@ii(#1){\pscircle@do(#1){\psk@radius}}
\def\pswedge{\pst@object{pswedge}}
\def\pswedge@i{\@ifnextchar({\pswedge@ii}{\pswedge@ii(0,0)}}
\def\pswedge@ii(#1)#2#3#4{%
\begin@ClosedObj
\pssetlength\pst@dimc{#2}
\pst@getangle{#3}\pst@tempa
\pst@getangle{#4}\pst@tempb
\pst@@getcoor{#1}%
\def\pst@linetype{1}%
\addto@pscode{%
\pst@coor
2 copy
moveto
\pst@number\pst@dimc \psk@dimen CLW mul sub % Adjusted radius
\pst@tempa \pst@tempb
arc
closepath}%
\showpointsfalse
\end@ClosedObj}
\def\tx@Ellipse{Ellipse }
\def\psellipse{\pst@object{psellipse}}
\def\psellipse@i(#1){\@ifnextchar(%
{\psellipse@ii(#1)}{\psellipse@ii(0,0)(#1)}}
\def\psellipse@ii(#1)(#2){%
\begin@ClosedObj
\pst@getcoor{#1}\pst@tempa
\pst@@getcoor{#2}%
\addto@pscode{%
0 360
\pst@coor
\ifdim\psk@dimen\p@=\z@\else
\psk@dimen CLW mul
dup 4 -1 roll sub neg 3 1 roll sub
\fi
\pst@tempa
\tx@Ellipse
closepath}%
\def\pst@linetype{2}%
\end@ClosedObj}
\def\multips{\@ifnextchar({\def\pst@par{}\multips@ii}{\multips@i}}
\def\multips@i#1{\def\pst@par{rot=#1}\multips@ii}
\def\multips@ii(#1){\@ifnextchar({\multips@iii(#1)}{\multips@iii(\z@,\z@)(#1)}}
\long\def\multips@iii(#1)(#2)#3#4{%
\begingroup
\use@par
\pst@getcoor{#1}\pst@tempa
\pst@@getcoor{#2}%
\pst@cnta=#3\relax
\init@pscode
\addto@pscode{%
\pst@tempa T \the\pst@cnta\space \pslbrace
gsave \ifx\psk@rot\@empty\else\psk@rot rotate \fi}%
\hbox to\z@{%
\def\init@pscode{%
\addto@pscode{%
gsave
\pst@number\pslinewidth SLW
\pst@usecolor\pslinecolor}}%
\def\use@pscode{\addto@pscode{grestore}}%
\def\psclip##1{\pst@misplaced\psclip}%
\def\nc@object##1##2##3##4{\pst@misplaced{node connection}}%
#4}%
\addto@pscode{grestore \pst@coor T \psrbrace repeat}%
\leavevmode
\use@pscode
\endgroup
\ignorespaces}
\def\scalebox#1{\pst@makebox{\@scalebox{#1}}}
\def\@scalebox#1{%
\begingroup
\pst@getscale{#1}\pst@tempa
\let\pst@tempc\pst@tempg
\let\pst@tempd\pst@temph
\@@scalebox
\endgroup}
\def\@@scalebox{%
\leavevmode
\hbox{%
\ifdim\pst@tempd\p@<\z@
\pst@dimg=\pst@tempd\ht\pst@hbox
\pst@dimh=\pst@tempd\dp\pst@hbox
\dp\pst@hbox=-\pst@dimg
\ht\pst@hbox=-\pst@dimh
\else
\ht\pst@hbox=\pst@tempd\ht\pst@hbox
\dp\pst@hbox=\pst@tempd\dp\pst@hbox
\fi
\pst@dima=\pst@tempc\wd\pst@hbox
\ifdim\pst@dima<\z@\kern-\pst@dima\fi
\pst@Verb{CP CP translate \pst@tempa \tx@NET}%
\hbox to \z@{\box\pst@hbox\hss}%
\pst@Verb{%
CP CP translate
1 \pst@tempc div 1 \pst@tempd div scale
\tx@NET}%
\ifdim\pst@dima>\z@\kern\pst@dima\fi}}
\pslongbox{Scalebox}{\scalebox}
\def\scaleboxto(#1,#2){\pst@makebox{\@scaleboxto(#1,#2)}}
\def\@scaleboxto(#1,#2){%
\begingroup
\pssetlength\pst@dima{#1}%
\pssetlength\pst@dimb{#2}%
\ifdim\pst@dima=\z@\else
\pst@divide{\pst@dima}{\wd\pst@hbox}\pst@tempc
\edef\pst@tempc{\pst@tempc\space}%
\fi
\ifdim\pst@dimb=\z@
\ifdim\pst@dima=\z@
\@pstrickserr{%
\string\scaleboxto\space dimensions cannot both be zero}\@ehpa
\def\pst@tempa{}%
\def\pst@tempc{1 }%
\def\pst@tempd{1 }%
\else
\let\pst@tempd\pst@tempc
\fi
\else
\pst@dimc=\ht\pst@hbox
\advance\pst@dimc\dp\pst@hbox
\pst@divide{\pst@dimb}{\pst@dimc}\pst@tempd
\edef\pst@tempd{\pst@tempd\space}%
\ifdim\pst@dima=\z@ \let\pst@tempc\pst@tempd \fi
\fi
\edef\pst@tempa{\pst@tempc \pst@tempd scale }%
\@@scalebox
\endgroup}
\pslongbox{Scaleboxto}{\scaleboxto}
\def\tx@Rot{Rot }
\def\rotateleft{\pst@makebox{\@rotateleft\pst@hbox}}
\def\@rotateleft#1{%
\leavevmode\hbox{\hskip\ht#1\hskip\dp#1\vbox{\vskip\wd#1%
\pst@Verb{90 \tx@Rot}
\vbox to \z@{\vss\hbox to \z@{\box#1\hss}\vskip\z@}%
\pst@Verb{-90 \tx@Rot}}}}
\def\rotateright{\pst@makebox{\@rotateright\pst@hbox}}
\def\@rotateright#1{%
\hbox{\hskip\ht#1\hskip\dp#1\vbox{\vskip\wd#1%
\pst@Verb{-90 \tx@Rot}
\vbox to \z@{\hbox to \z@{\hss\box#1}\vss}%
\pst@Verb{90 \tx@Rot}}}}
\def\rotatedown{\pst@makebox{\@rotatedown\pst@hbox}}
\def\@rotatedown#1{%
\hbox{\hskip\wd#1\vbox{\vskip\ht#1\vskip\dp#1%
\pst@Verb{180 \tx@Rot}%
\vbox to \z@{\hbox to \z@{\box#1\hss}\vss}%
\pst@Verb{-180 \tx@Rot}}}}
\pslongbox{Rotateleft}{\rotateleft}
\pslongbox{Rotateright}{\rotateright}
\pslongbox{Rotatedown}{\rotatedown}
\def\pst@starbox{%
\setbox\pst@hbox\hbox{\psframebox*[boxsep=false]{\unhbox\pst@hbox}}}
\def\pst@@makesmall#1{%
\setbox#1=\hbox to\z@{\hss\vbox to \z@{\vss\box#1\vss}\hss}}
\def\pst@@@makesmall#1{%
\pst@dimh=\psk@xref\wd#1%
\ifx\psk@yref\relax
\pst@dimg=\dp#1%
\else
\pst@dimg=\psk@yref\ht#1%
\advance\pst@dimg\psk@yref\dp#1%
\fi
\setbox#1=\hbox to\z@{%
\kern-\pst@dimh\vbox to\z@{\vss\box#1\kern-\pst@dimg}\hss}}
\def\psset@ref#1{\pst@expandafter\psset@@ref{#1}\@empty,,\@nil}
\def\psset@@ref#1#2,#3,#4\@nil{%
\def\psk@xref{.5}%
\def\psk@yref{.5}%
\let\pst@makesmall\pst@@@makesmall
\ifx\@empty#3\@empty
\@nameuse{getref@#1}%
\@nameuse{getref@#2}%
\else
\pst@checknum{#1#2}\psk@xref
\pst@checknum{#3}\psk@yref
\fi}
\def\getref@c{\let\pst@makesmall\pst@@makesmall}
\def\getref@t{\def\psk@yref{1}}
\def\getref@b{\def\psk@yref{0}}
\def\getref@B{\let\psk@yref\relax}
\def\getref@l{\def\psk@xref{0}}
\def\getref@r{\def\psk@xref{1}}
\psset@ref{c}
\def\psset@rot#1{%
\pst@expandafter{\@ifnextchar*{\psset@@@rot}{\psset@@rot}}{#1}\@nil}
\def\psset@@rot#1\@nil{%
\def\next##1@#1=##2@##3\@nil{%
\ifx\relax##2%
\pst@getangle{#1}\psk@rot
\else
\def\psk@rot{##2}%
\fi}%
\expandafter\next\pst@rottable @#1=\relax @\@nil}
\def\psset@@@rot#1#2\@nil{%
\psset@@rot#2\@nil
\edef\psk@rot{\pst@rotlist \ifx\psk@rot\@empty\else\psk@rot add \fi}}
\def\pst@rotlist{mark RAngle /a ED cleartomark a neg }
\def\pst@rottable{%
@0=%
@U=%
@L=90 %
@D=180 %
@R=-90 %
@N=\pst@rotlist
@W=\pst@rotlist 90 add %
@S=\pst@rotlist 180 add %
@E=\pst@rotlist 90 sub }
\psset@rot{0}
\def\tx@RotBegin{RotBegin }
\def\tx@RotEnd{RotEnd }
\def\pst@rotate#1#2{%
\ifx#1\@empty\else
\setbox#2=\hbox{\pst@Verb{#1 \tx@RotBegin}\box#2\pst@Verb{\tx@RotEnd}}%
\fi}
\def\psput@cartesian#1{%
\hbox to \z@{\kern\pst@dimg{\vbox to \z@{\vss\box#1\vskip\pst@dimh}\hss}}}
\def\psput@special#1{%
\hbox{%
\pst@Verb{{ \pst@coor } \tx@PutCoor \tx@PutBegin}%
\box#1%
\pst@Verb{\tx@PutEnd}}}
\def\tx@PutCoor{PutCoor }
\def\tx@PutBegin{PutBegin }
\def\tx@PutEnd{PutEnd }
\def\rput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\rput@i}{\rput@ii}}}
\def\rput@i[#1]{\addto@par{ref={#1}}\rput@ii}
\def\rput@ii{\@ifnextchar({\rput@iv}{\rput@iii}}
\def\rput@iii#1{\addto@par{rot={#1}}\@ifnextchar({\rput@iv}{\rput@iv(\z@,\z@)}}
\def\rput@iv(#1){\pst@killglue\pst@makebox{\rput@v{#1}}}
\def\rput@v#1{%
\begingroup
\use@par
\if@star\pst@starbox\fi
\pst@makesmall\pst@hbox
\pst@rotate\psk@rot\pst@hbox
\psput@{#1}\pst@hbox
\endgroup
\ignorespaces}
\def\multirput{%
\def\pst@par{}%
\pst@ifstar{\@ifnextchar[{\multirput@i}{\multirput@ii}}}
\def\multirput@i[#1]{\addto@par{ref={#1}}\multirput@ii}
\def\multirput@ii{\@ifnextchar({\multirput@iv}{\multirput@iii}}
\def\multirput@iii#1{\addto@par{rot={#1}}\multirput@iv}
\def\multirput@iv(#1){%
\@ifnextchar({\multirput@v(#1)}{\multirput@v(\z@,\z@)(#1)}}
\def\multirput@v(#1,#2)(#3,#4)#5{%
\pst@makebox{\multirput@vi(#1,#2)(#3,#4){#5}}}
\def\multirput@vi(#1,#2)(#3,#4)#5{%
\begingroup
\use@par
\if@star\pst@starbox\fi
\pst@makesmall\pst@hbox
\pst@rotate\psk@rot\pst@hbox
\pssetxlength\pst@dima{#1}%
\pssetylength\pst@dimb{#2}%
\pssetxlength\pst@dimc{#3}%
\pssetylength\pst@dimd{#4}%
\pst@cntg=#5\relax
\pst@cnth=\@ne
\leavevmode
\loop
\vbox to \z@{%
\vss
\hbox to \z@{\kern\pst@dima\copy\pst@hbox\hss}%
\vskip\pst@dimb}%
\ifnum\pst@cntg>\pst@cnth
\advance\pst@dima\pst@dimc
\advance\pst@dimb\pst@dimd
\advance\pst@cnth\@ne
\repeat
\endgroup
\ignorespaces}
\newif\if@fixedradius
\def\cput{\pst@object{cput}}
\def\cput@i{\@fixedradiusfalse\cput@ii}
\def\cput@ii{\pst@killglue\@ifnextchar({\cput@iv}{\cput@iii}}
\def\cput@iii#1{%
\addto@par{rot={#1}}%
\@ifnextchar({\cput@iv}{\cput@iv(\z@,\z@)}}
\def\cput@iv(#1){\pst@makebox{\cput@v{#1}}}
\def\cput@v#1{%
\begingroup
\use@par
\setbox\pst@hbox=\hbox{%
\psboxsepfalse
\if@fixedradius\psCirclebox@ii\else\pscirclebox@ii\fi}%
\pst@@makesmall\pst@hbox
\pst@rotate\psk@rot\pst@hbox
\psput@{#1}\pst@hbox
\endgroup
\ignorespaces}
\def\Cput{\pst@object{Cput}}
\def\Cput@i{\@fixedradiustrue\cput@ii}
\newdimen\pslabelsep
\def\psset@labelsep#1{\pssetlength\pslabelsep{#1}}
\psset@labelsep{5pt}
\def\psset@refangle#1{\pst@expandafter\psset@@refangle{#1}\@nil}
\def\psset@@refangle#1\@nil{%
\def\next##1@#1=##2"##3@##4\@nil{%
\ifx\relax##2%
\pst@getangle{#1}\psk@refangle
\def\psk@uputref{}%
\else
\def\psk@refangle{##2 }%
\def\psk@uputref{##3}%
\fi}%
\expandafter\next\pst@refangletable @#1=\relax"@\@nil}
\def\pst@refangletable{%
@r=0"20%
@u=90"02%
@l=180"10%
@d=-90"01%
@ur=45"22%
@ul=135"12%
@dr=-135"21%
@dl=-45"11}
\psset@refangle{0}
% DG/SR modification begin - Mar. 24, 1999 - Patch 10
%\def\uput{\def\pst@par{}\@ifnextchar[{\uput@ii}{\uput@i}}
\def\uput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\uput@ii}{\uput@i}}} 
% DG/SR modification end
\def\uput@i#1{\addto@par{labelsep=#1}\uput@ii}
\def\uput@ii[#1]{%
\addto@par{refangle={#1}}%
\@ifnextchar({\uput@iv}{\uput@iii}}
\def\uput@iii#1{%
\addto@par{rot={#1}}%
\@ifnextchar({\uput@iv}{\uput@iv(\z@,\z@)}}
\def\uput@iv(#1){\pst@killglue\pst@makebox{\uput@v{#1}}}
\def\uput@v#1{%
\begingroup
\use@par
\if@star\pst@starbox\fi
\uput@vi
\psput@{#1}\pst@hbox
\endgroup
\ignorespaces}
\def\uput@vi{%
\ifx\psk@uputref\@empty
\uput@vii\tx@UUput{}%
\else
\ifx\psk@rot\@empty
\expandafter\uput@viii\psk@uputref
\else
\uput@vii\tx@UUput{}%
\fi
\fi}
\def\uput@vii#1#2{%
\edef\pst@coor{%
\pst@number\pslabelsep
#2%
\pst@number{\wd\pst@hbox}%
\pst@number{\ht\pst@hbox}%
\pst@number{\dp\pst@hbox}%
\psk@refangle\space \ifx\psk@rot\@empty\else\psk@rot\space sub \fi
\tx@Uput #1}%
\setbox\pst@hbox=\hbox to\z@{\hss\vbox to\z@{\vss\box\pst@hbox\vss}\hss}%
\setbox\pst@hbox=\psput@special\pst@hbox
\ifx\psk@rot\@empty\else\pst@rotate\psk@rot\pst@hbox\fi}
\def\uput@viii#1#2{%
\ifnum#1>\z@\ifnum#2>\z@\pslabelsep=.707\pslabelsep\fi\fi
\setbox\pst@hbox=\vbox to\z@{%
\ifnum#2=1 \vskip\pslabelsep\else\vss\fi
\hbox to\z@{%
\ifnum#1=2 \hskip\pslabelsep\else\hss\fi
\box\pst@hbox
\ifnum#1=1 \hskip\pslabelsep\else\hss\fi}%
\ifnum#2=2 \vskip\pslabelsep\else\vss\fi}}
\def\tx@Uput{Uput }
\def\tx@UUput{UUput }
\def\Rput{\def\pst@par{}\pst@ifstar{\@ifnextchar[{\Rput@ii}{\Rput@i}}}
\def\Rput@i#1{\addto@par{labelsep=#1}\Rput@ii}
\def\Rput@ii[#1]{\addto@par{ref={#1}}\@ifnextchar({\Rput@iv}{\Rput@iii}}
\def\Rput@iii#1{\addto@par{rot={#1}}\@ifnextchar({\Rput@iv}{\Rput@iv(\z@,\z@)}}
\def\Rput@iv(#1){\pst@killglue\pst@makebox{\Rput@v{#1}}}
\def\Rput@v#1{%
\begingroup
\use@par
\if@star\pst@starbox\fi
\Rput@vi
\pst@makesmall\pst@hbox
\pst@rotate\psk@rot\pst@hbox
\psput@{#1}\pst@hbox
\endgroup
\ignorespaces}
\def\Rput@vi{%
\pst@dimg=\dp\pst@hbox
\advance\pst@dimg\pslabelsep
\dp\pst@hbox=\pst@dimg
\pst@dimg=\ht\pst@hbox
\advance\pst@dimg\pslabelsep
\ht\pst@hbox=\pst@dimg
\setbox\pst@hbox\hbox{\kern\pslabelsep\box\pst@hbox\kern\pslabelsep}}%
\def\oldpsput{%
\def\pst@par{}\pst@ifstar{\@ifnextchar[{\oldpsput@i}{\oldpsput@ii}}}
\def\oldpsput@i[#1]{\addto@par{ref={#1}}\oldpsput@ii}
\def\oldpsput@ii{\@ifnextchar<{\oldpsput@iii}{\oldpsput@iv}}
\def\oldpsput@iii<#1>{\rput@iii{#1}}
\def\OldPsput{\let\psput\oldpsput}
\def\NewPsput{\let\psput\rput}
\def\pspicture{\begingroup\pst@ifstar\pst@picture}
\def\pst@picture{%
\@ifnextchar[{\pst@@picture}{\pst@@picture[0]}}
\def\pst@@picture[#1]#2(#3,#4){%
\@ifnextchar({\pst@@@picture[#1](#3,#4)}%
{\pst@@@picture[#1](0,0)(#3,#4)}}
\def\pst@@@picture[#1](#2,#3)(#4,#5){%
\pssetxlength\pst@dima{#2}%
\pssetylength\pst@dimb{#3}%
\pssetxlength\pst@dimc{#4}%
\pssetylength\pst@dimd{#5}%
\ifdim\pst@dima>\pst@dimc
\pst@dimg=\pst@dima
\pst@dima=\pst@dimc
\pst@dimc=\pst@dimg
\fi
\ifdim\pst@dimb>\pst@dimd
\pst@dimg=\pst@dimb
\pst@dimb=\pst@dimd
\pst@dimd=\pst@dimg
\fi
\def\pst@tempa{#1}%
\setbox\pst@hbox=\hbox\bgroup
\begingroup\KillGlue
\@ifundefined{@latexerr}{}{\let\unitlength\psunit}%
\edef\pic@coor{(#2,#3)(#2,#3)(#4,#5)}\ignorespaces}
\def\pic@coor{(0,0)(0,0)(10,10)}
\def\endpspicture{%
\pst@killglue
\endgroup
\egroup
\ifdim\wd\pst@hbox=\z@\else
%\@pstrickserr{Extraneous space in the pspicture environment}%
%{Type \space <return> \space to procede.}%
\fi
\ht\pst@hbox=\pst@dimd
\dp\pst@hbox=-\pst@dimb
\setbox\pst@hbox=\hbox{%
\kern-\pst@dima
\ifx\pst@tempa\@empty\else
\advance\pst@dimd-\pst@dimb
\pst@dimd=\pst@tempa\pst@dimd
\advance\pst@dimd\pst@dimb
\lower\pst@dimd
\fi
\box\pst@hbox
\kern\pst@dimc}%
\if@star\setbox\pst@hbox=\hbox{\clipbox@@\z@}\fi
\leavevmode\box\pst@hbox
\endgroup}
\@namedef{pspicture*}{\pspicture*}
\@namedef{endpspicture*}{\endpspicture}
\def\tx@BeginOL{BeginOL }
\def\tx@InitOL{InitOL }
\def\pst@initoverlay#1{\pst@Verb{\tx@InitOL /TheOL (#1) def}}
\def\AltOverlayMode{%
\def\pst@initoverlay##1{%
\pst@Verb{%
\tx@InitOL
/Visible { initclip } def
/Invisible {
CP newpath OLUnit itransform moveto clip newpath moveto
} def
/TheOL (##1) def}}}
\def\pst@overlay#1{%
\edef\curr@overlay{#1}%
\pst@Verb{(#1) BOL}%
\aftergroup\pst@endoverlay}
\def\pst@endoverlay{%
\pst@Verb{(\curr@overlay) BOL}}
\def\curr@overlay{all}
\newbox\theoverlaybox
\def\overlaybox{%
\global\setbox\theoverlaybox=\hbox\bgroup
\begingroup
\let\psoverlay\pst@overlay
\def\overlaybox{%
\@pstrickserr{Overlays cannot be nested}\@eha}%
\def\putoverlaybox{%
\@pstrickserr{You must end the overlay box
before using \string\putoverlaybox}}%
\psoverlay{main}%
\ignorespaces}
\def\endoverlaybox{\endgroup\egroup}
\def\putoverlaybox#1{%
\hbox{\pst@initoverlay{#1}\copy\theoverlaybox}}
\def\psoverlay{\@pstrickserr{\string\psoverlay\space
can only be used after \string\overlaybox}}
\ifx\pstcustomize\relax \input pstricks.con \fi
\catcode`\@=\PstAtCode\relax
%
\endinput
%%
%% END: pstricks.tex

math0108150.extracted_bib
\begin{thebibliography}{10}

\bibitem{Andrews:tsscpp}
George~E. Andrews, \emph{Plane partitions {V}: {The T. S. S. C. P. P.}
  conjecture}, J. Combin. Theory Ser. A \textbf{66} (1994), no.~1, 28--39.

\bibitem{Biggs:algebraic}
Norman Biggs, \emph{Algebraic potential theory on graphs}, Bull. London Math.
  Soc. \textbf{29} (1997), no.~6, 641--682.

\bibitem{CEKZ:triangular}
Mihai Ciucu, Theresia Eisenk\"olbl, Christian Krattenthaler, and Douglas Zare,
  \emph{Enumeration of lozenge tilings of hexagons with a central triangular
  hole}, \mbox{arXiv:math.CO/9912053}.

\bibitem{CK:centered}
Mihai Ciucu and Christian Krattenthaler, \emph{The number of centered lozenge
  tilings of a symmetric hexagon}, J. Combin. Theory Ser. A \textbf{86} (1999),
  no.~1, 103--126, \mbox{arXiv:math.CO/9712209}.

\bibitem{Kuperberg:eklp1}
Noam Elkies, Greg Kuperberg, Michael Larsen, and James Propp,
  \emph{Alternating-sign matrices and domino tilings, {I}}, J. Algebraic
  Combin. \textbf{1} (1992), no.~2, 111--132.

\bibitem{Kuperberg:eklp2}
\bysame, \emph{Alternating-sign matrices and domino tilings, {II}}, J.
  Algebraic Combin. \textbf{1} (1992), no.~3, 219--234.

\bibitem{Fisher:planar}
Michael~E. Fisher, \emph{On the dimer solution of planar {Ising} models}, J.
  Math. Phys. \textbf{7} (1966), 1776--1781.

\bibitem{GV:partitions}
Ira Gessel and Xavier~G. Viennot, \emph{Determinants, paths, and plane
  partitions}, 1989, Preprint.

\bibitem{GV:binomial}
Ira~M. Gessel and Xavier~G. Viennot, \emph{Binomial determinants, paths, and
  hook length formulas}, Adv. Math. \textbf{58} (1985), no.~3, 300--321.

\bibitem{Jockusch:perfect}
William Jockusch, \emph{Perfect matchings and perfect squares}, J. Combin.
  Theory Ser. A \textbf{67} (1994), 100--115.

\bibitem{Kasteleyn:crystal}
P.~W. Kasteleyn, \emph{Graph theory and crystal physics}, Graph theory and
  theoretical physics (F.~Harary, ed.), Academic Press, 1967.

\bibitem{Kenyon:local}
Richard Kenyon, \emph{Local statistics of lattice dimers}, Ann. Inst. H.
  Poincar\'e Probab. Statist. \textbf{33} (1997), 591--618,
  \mbox{arXiv:math.CO/0105054}.

\bibitem{KPW:trees}
Richard Kenyon, James Propp, and David Wilson, \emph{Trees and matchings},
  Electron. J. Combin. \textbf{7} (2000), \#R25, \mbox{arXiv:math.CO/9903025}.

\bibitem{Krattenthaler:advanced}
Christian Krattenthaler, \emph{Advanced determinant calculus}, S\'eminaire
  Lotharingien Combin. \textbf{42} (1999), B42q, \mbox{arXiv:math.CO/9902004}.

\bibitem{Kuperberg:perdet}
Greg Kuperberg, \emph{Symmetries of plane partitions and the
  permanent-determinant method}, J. Combin. Theory Ser. A \textbf{68} (1994),
  no.~1, 115--151.

\bibitem{Kuperberg:fun}
\bysame, \emph{An exploration of the permanent-determinant method}, Electron.
  J. Combin. \textbf{5} (1998), no.~\#R46, 16pp, \mbox{arXiv:math.CO/9810091}.

\bibitem{Lindstrom:vector}
B.~Lindstr\"om, \emph{On the vector representations of induced matroids}, Bull.
  London Math. Soc. \textbf{5} (1973), 85--90.

\bibitem{Lorenzini:attached}
Dino~J. Lorenzini, \emph{A finite group attached to the {Laplacian} of a
  graph}, Discrete Math. \textbf{91} (1991), no.~3, 277--282.

\bibitem{Merris:unimodular}
Russell Merris, \emph{Unimodular equivalence of graphs}, Linear Algebra Appl.
  \textbf{173} (1992), 181--189.

\bibitem{MRR:asm}
William~H. Mills, David~P. Robbins, and Howard Rumsey, \emph{Alternating-sign
  matrices and descending plane partitions}, J. Combin. Theory Ser. A
  \textbf{34} (1983), no.~3, 340--359.

\bibitem{Percus:dimer}
Jerome~K. Percus, \emph{One more technique for the dimer problem}, J. Math.
  Phys. \textbf{10} (1969), 1881--1888.

\bibitem{Propp:progress}
James Propp, \emph{Enumeration of matchings: problems and progress}, New
  perspectives in algebraic combinatorics ({Berkeley, CA}, 1996--97), Cambridge
  Univ. Press, Cambridge, 1999, \mbox{arXiv:math.CO/9904150}, pp.~255--291.

\bibitem{Rudin:fourier}
Walter Rudin, \emph{Fourier analysis on groups}, Wiley Interscience, 1962.

\bibitem{SZ:dimer}
Horst Sachs and Holger Zernitz, \emph{Remark on the dimer problem}, Discrete
  Appl. Math. \textbf{51} (1994), no.~1-2, 171--179.

\bibitem{Saldanha:singular}
Nicolau~C. Saldanha, \emph{Singular polynomials of generalized {Kasteleyn}
  matrices}, \mbox{arXiv:math.CO/0101002}.

\bibitem{Stanley:symmetries}
Richard~P. Stanley, \emph{Symmetries of plane partitions}, J. Combin. Theory
  Ser. A \textbf{43} (1986), no.~1, 103--113.

\bibitem{Stanley:enumerative2}
\bysame, \emph{Enumerative combinatorics}, vol.~2, Cambridge University Press,
  Cambridge, England, 1999.

\bibitem{Steane:review}
Andrew Steane, \emph{Quantum computing}, Rep. Progr. Phys. \textbf{61} (1998),
  no.~2, 117--173, \mbox{arXiv:quant-ph/9708022}.

\bibitem{Stembridge:paths}
John~R. Stembridge, \emph{Non-intersecting paths, {Pfaffians}, and plane
  partitions}, Adv. Math. \textbf{83} (1990), no.~1, 96--131.

\bibitem{Stembridge:q-1}
\bysame, \emph{Some hidden relations involving the ten symmetry classes of
  plane partitions}, J. Combin. Theory Ser. A \textbf{68} (1994), 372--409.

\bibitem{Stembridge:enumeration}
\bysame, \emph{The enumeration of totally symmetric plane partitions}, Adv.
  Math. \textbf{111} (1995), no.~2, 227--243.

\bibitem{Tokuyama:gelfand}
Takeshi Tokuyama, \emph{A generating function of strict {Gel'fand} patterns and
  some formulas on characters of general linear groups}, J. Math. Soc. Japan
  \textbf{40} (1988), 671--685.

\bibitem{Waerden:reichweite}
B.~L. van~der Waerden, \emph{Die lange {Reichweite} der regelmaessigen
  {Atomanordnung} in {Mischkristallen}}, Zeitschrift {f\"ur} Physik
  \textbf{118} (1941), 473--488.

\bibitem{Yang:thesis}
Bo-Yin Yang, \emph{Two enumeration problems about the {Aztec} diamonds}, Ph.D.
  thesis, Massachusetts Institute of Technology, 1991.

\end{thebibliography}