Decomposing Non-Redundant Sharing \\ by Complementation
ENEA ZAFFANELLA
Department of Mathematics
PATRICIA M. HILL\thanks{This work was partly supported by EPSRC under grant GR/M05645.}
School of Computing
Leeds
ROBERTO BAGNARA\thanks{The work of the first and third authors has been partly supported by MURST project ``Certificazione automatica di programmi mediante interpretazione astratta.''}
Complementation, the inverse of the reduced product operation, is a technique for systematically finding minimal decompositions of abstract domains. Fil\'e and Ranzato advanced the state of the art by introducing a simple method for computing a complement. As an application, they considered the extraction by complementation of the pair-sharing domain $\PS$ from the Jacobs and Langen's set-sharing domain $\SH$. However, since the result of this operation was still $\SH$, they concluded that $\PS$ was too abstract for this. Here, we show that the source of this result lies not with $\PS$ but with $\SH$ and, more precisely, with the redundant information contained in $\SH$ with respect to ground-dependencies and pair-sharing. In fact, a proper decomposition is obtained if the non-redundant version of $\SH$, $\PSD$, is substituted for $\SH$. To establish the results for $\PSD$, we define a general schema for subdomains of $\SH$ that includes $\PSD$ and $\Def$ as special cases. This sheds new light on the structure of $\PSD$ and exposes a natural though unexpected connection between $\Def$ and $\PSD$. Moreover, we substantiate the claim that complementation alone is not sufficient to obtain truly minimal decompositions of domains. The right solution to this problem is to first remove redundancies by computing the quotient of the domain with respect to the observable behavior, and only then decompose it by complementation.
TPLP01R3.tex
\documentclass{tlp}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{stmaryrd}
\usepackage{pst-tree}
\usepackage[matrix,arrow,ps,dvips]{xy}
\usepackage{harvard}

%% Special letters denoting sets and algebras
\providecommand*{\Nset}{\mathbb{N}}            % Naturals
\newcommand*{\extNset}{\mathbb{N}_\infty}      % Extended naturals
\providecommand*{\Oset}{\mathbb{O}}            % Ordinals
\providecommand*{\Qset}{\mathbb{Q}}            % Rationals
\providecommand*{\Rset}{\mathbb{R}}            % Reals
\newcommand*{\extRset}{\Rset_\infty}           % Extended reals
\providecommand*{\Zset}{\mathbb{Z}}            % Integers

%% Et al: how should be typeset?
%% The LNCS style rules says in Roman,
%% the Merriam-Websters ``Guide to Punctuation and Style'' says in Roman,
%% but the TPLP biblio style says in Italic.
\providecommand{\etal}{\textit{et al.}}

%% Calligraphic alphabet
\newcommand*{\cD}{\mathcal{D}}
\newcommand*{\cH}{\mathcal{H}}
\newcommand*{\cN}{\mathcal{N}}
\newcommand*{\cR}{\mathcal{R}}
\newcommand*{\cT}{\mathcal{T}}

%% Domain and co-domain of a function
\newcommand*{\dom}{\mathop{\mathrm{dom}}\nolimits}
\newcommand*{\cod}{\mathop{\mathrm{cod}}\nolimits}

%% Declarators for functions and relations
\newcommand*{\reld}[3]{\mathord{#1}\subseteq#2\times#3}
\newcommand*{\fund}[3]{\mathord{#1}\colon#2\rightarrow#3}

%% Things that hold by definition
\newcommand{\defrel}[1]{\mathrel{\buildrel \mathrm{def} \over {#1}}}
\newcommand{\defeq}{\defrel{=}}
\newcommand{\defiff}{\defrel{\Longleftrightarrow}}

%% Summaries for theorem-like environments
\newcommand{\summary}[1]{\textrm{\textbf{\textup{#1}}}} 

%% Set theory
\newcommand{\card}{\mathop{\#}\nolimits}
\newcommand*{\sseq}{\subseteq}
\newcommand*{\sslt}{\subset}
\newcommand*{\Sseq}{\supseteq}
\newcommand*{\Ssgt}{\supset}
\newcommand{\Nsseq}{\nsubseteq}
\newcommand*{\union}{\cup}
\newcommand*{\inters}{\cap}
\newcommand*{\setdiff}{\setminus}
\newcommand*{\bigunion}{\bigcup}
\newcommand*{\biginters}{\bigcap}

%% Set-theory-like: squared version
\newcommand*{\sqsseq}{\sqsubseteq}

%% All variables and variables in a syntactic object
\newcommand*{\Vars}{\mathord{\mathit{Vars}}}
\newcommand*{\vars}{\mathop{\mathit{vars}}\nolimits}

%% Terms
\newcommand*{\Terms}{\cT_{\Vars}}

%% Lattice theory
\newcommand{\glb}{\mathop{\mathrm{glb}}\nolimits}
\newcommand{\lub}{\mathop{\mathrm{lub}}\nolimits}
\newcommand{\uco}{\mathop{\mathrm{uco}}\nolimits}

%% Logical quantifiers stuff
\newcommand{\st}{\mathrel{.}}
\newcommand{\itc}{\mathrel{:}}

%% China
\newcommand{\china}{\textmd{\textsc{China}}}

%% CLP languages
\newcommand*{\CLPR}{CLP($\cR$)}
\newcommand*{\HofN}{{\cH_{\mkern-4mu\cN}}}
\newcommand*{\CLPHofN}{\textup{CLP($\HofN$)}}

%% C++
\newcommand*{\Cplusplus}{{C\nolinebreak[4]\hspace{-.05em}\raisebox{.4ex}{\tiny\bf ++}}}

%% The Pattern domain
\newcommand*{\Pattern}{\mathop{\mathrm{Pattern}}\nolimits}

%% Assignments
\newcommand{\takes}{\mathrel{:=}}

% Set-sharing
\newcommand*{\VI}{\mathit{VI}}
\newcommand*{\SG}{\mathit{SG}}
\newcommand*{\SH}{\mathit{SH}}
\newcommand*{\sh}{\mathit{sh}}
\newcommand*{\SSl}{\mathit{SS}}
\newcommand*{\leqSSl}{\mathrel{\preceq_\mathit{\scriptscriptstyle SS}}}

% The new domain
\newcommand*{\SSm}{{\mathit{SS}^\rho}}
\newcommand*{\SHm}{{\mathit{SH}^\rho}}
\newcommand*{\equivrho}{\mathrel{\equiv_\rho}}

% Pair-sharing
\newcommand*{\pairs}{\mathop{\mathrm{pairs}}\nolimits}
\newcommand*{\Pairs}{\mathop{\mathrm{Pairs}}\nolimits}
\newcommand*{\Down}{\mathop{\mathrm{Down}}\nolimits}
\newcommand*{\PS}{\mathit{PS}}
\newcommand*{\ps}{\mathit{ps}}
\newcommand*{\leqPS}{\mathrel{\preceq_\mathit{\scriptscriptstyle PS}}}
\newcommand*{\NleqPS}{\mathrel{\npreceq_\mathit{\scriptscriptstyle PS}}}

% The set of all substitutions
\newcommand*{\Subst}{\mathit{Subst}}

% Operations on set-sharing
\newcommand*{\rel}{\mathop{\mathrm{rel}}\nolimits}
\newcommand*{\irel}{\mathop{\overline{\mathrm{rel}}}\nolimits}
\newcommand*{\bin}{\mathop{\mathrm{bin}}\nolimits}
\newcommand*{\proj}{\mathop{\mathrm{proj}}\nolimits}
\newcommand*{\Proj}{\mathop{\mathrm{Proj}}\nolimits}
\newcommand*{\mgu}{\mathop{\mathrm{mgu}}\nolimits}
\newcommand*{\amgu}{\mathop{\mathrm{amgu}}\nolimits}
\newcommand*{\Amgu}{\mathop{\mathrm{Amgu}}\nolimits}

\newcommand*{\Defminus}{{\Def^{\mathord{-}}}}
\newcommand{\ucomeet}{\mathbin{\sqcap}}
\newcommand{\bigucomeet}{\mathop{\bigsqcap}\limits}

% Tuple-sharing
\newcommand*{\tuples}{\mathop{\mathrm{tuples}}\nolimits}
\newcommand*{\PSD}{\mathit{PSD}}
\newcommand*{\TSD}{\mathit{TSD}}
\newcommand*{\TS}{\mathit{TS}}

\newcommand*{\Bind}{\mathit{Bind}}
\newcommand*{\SSubst}{\mathit{VSubst}}

\newcommand{\occ}{\mathop{\mathrm{occ}}\nolimits}
\newcommand{\occbang}{\mathop{\mathrm{occ!}}\nolimits}
\newcommand*{\compose}{\mathbin{\circ}}

%% Lattice symbols etc.
\newcommand*{\Moore}{\mathop{\mathrm{Moore}}\nolimits}
\newcommand*{\dAtoms}{\mathop{\mathrm{dAtoms}}\nolimits}
\newcommand*{\MI}{\mathop{\mathrm{MI}}\nolimits}
\newcommand*{\idc}{\mathit{id}_{\scriptscriptstyle C}}
\newcommand*{\idsh}{\mathit{id}_{\scriptscriptstyle \SH}}
\newcommand*{\idshplus}{\mathit{id}_{\scriptscriptstyle \SH^+}}
\newcommand*{\idPSDplus}{\mathit{id}_{\scriptscriptstyle \PSD^+}}
\newcommand*{\idPSD}{\mathit{id}_{\scriptscriptstyle \PSD}}
\newcommand*{\idDef}{\mathit{id}_{\scriptscriptstyle \Def}}
\newcommand*{\idSTk}{\mathit{id}_{\scriptscriptstyle \TSDk}}
\newcommand*{\op}{\mathop{\mathrm{op}}\nolimits}

\newcommand*{\PSDplus}{{\PSD^+}}
\newcommand*{\PSDplusplus}{{\PSD^{\mathord{\ddagger}}}}
\newcommand*{\PSDoplus}{{\PSD^{\mathord{\oplus}}}}
\newcommand*{\PSDDefplus}{{\PSD^+_{\scriptscriptstyle \Def}}}
\newcommand*{\SHDefplus}{{\SH^+_{\scriptscriptstyle \Def}}}
\newcommand*{\SHPSDplus}{{\SH^+_{\scriptscriptstyle \PSD}}}
\newcommand*{\Defoplus}{{\Def^{\mathord{\oplus}}}}

\newcommand*{\Def}{\mathit{Def}}
\newcommand*{\Pos}{\mathit{Pos}}
\newcommand*{\ScozzariShPSh}{\mathsf{Sh}^\mathsf{PSh}}
\newcommand*{\JonesSondG}{\mathsf{G}}
\newcommand*{\Prop}{\mathit{Prop}}
\newcommand*{\Con}{\mathit{Con}}

\newcommand*{\SHk}{{\SH_k}}
\newcommand*{\SHkplus}{{\SH^+_k}}
\newcommand*{\SHjplus}{{\SH^+_j}}

\newcommand*{\TSDone}{{\TSD_1}}
\newcommand*{\TSDoneminus}{\TSD_1^{\mathord{-}}}
\newcommand*{\TSDtwo}{{\TSD_2}}
\newcommand*{\TSDtwoplus}{\TSD_2^{\mathord{+}}}
\newcommand*{\TSDtwoplusplus}{\TSD_2^{\mathord{\ddagger}}}
\newcommand*{\TSDi}{{\TSD_i}}
\newcommand*{\TSDj}{{\TSD_j}}
\newcommand*{\TSDk}{{\TSD_k}}
\newcommand*{\TSDn}{{\TSD_n}}

\newcommand*{\TSone}{{\TS_1}}
\newcommand*{\TStwo}{{\TS_2}}
\newcommand*{\TSi}{{\TS_{\!i}}}
\newcommand*{\TSj}{{\TS_{\!j}}}
\newcommand*{\TSh}{{\TS_h}}
\newcommand*{\TSk}{{\TS_k}}
\newcommand*{\TSn}{{\TS_n}}

\newcommand*{\rhoDef}{\mathop{\rho_{\scriptscriptstyle \Def}}}
\newcommand*{\rhoCon}{\mathop{\rho_{\scriptscriptstyle \Con}}}
\newcommand*{\rhoPS}{\mathop{\rho_{\scriptscriptstyle \PS}}}
\newcommand*{\rhoPSprime}{\mathop{\rho_{\scriptscriptstyle \PS'}}}
\newcommand*{\rhoPSD}{\mathop{\rho_{\scriptscriptstyle \PSD}}}
\newcommand*{\rhoPSDplus}{\mathop{\rho_{\scriptscriptstyle \PSD^+}}}
\newcommand*{\rhoPSDplusplus}{\mathop{\rho_{\scriptscriptstyle \PSDplusplus}}}
\newcommand*{\rhoSHk}{\mathop{\rho_{\scriptscriptstyle \SH_k}}}

\newcommand*{\rhoTSDone}{\mathop{\rho_{\scriptscriptstyle \TSDone}}}
\newcommand*{\rhoTSDtwo}{\mathop{\rho_{\scriptscriptstyle \TSDtwo}}}
\newcommand*{\rhoTSDj}{\mathop{\rho_{\scriptscriptstyle \TSDj}}}
\newcommand*{\rhoTSDk}{\mathop{\rho_{\scriptscriptstyle \TSDk}}}
\newcommand*{\rhoTSDn}{\mathop{\rho_{\scriptscriptstyle \TSDn}}}

\newcommand*{\rhoTSone}{\mathop{\rho_{\scriptscriptstyle \TSone}}}
\newcommand*{\rhoTStwo}{\mathop{\rho_{\scriptscriptstyle \TStwo}}}
\newcommand*{\rhoTSj}{\mathop{\rho_{\scriptscriptstyle \TSj}}}
\newcommand*{\rhoTSh}{\mathop{\rho_{\scriptscriptstyle \TSh}}}
\newcommand*{\rhoTSk}{\mathop{\rho_{\scriptscriptstyle \TSk}}}
\newcommand*{\rhoTSn}{\mathop{\rho_{\scriptscriptstyle \TSn}}}

\newcommand*{\meet}{\wedge}
\newcommand*{\bigmeet}{\bigwedge}
\newcommand*{\join}{\vee}
\newcommand*{\bigjoin}{\bigvee}

\newcommand*{\sqsslt}{\sqsubset}

\newtheorem{thm}{Theorem}
\newtheorem{cor}{Corollary}
\newtheorem{prop}{Proposition}
\newtheorem{lem}{Lemma}
\newtheorem{exmp}{Example}
\newtheorem{defn}{Definition}

\begin{document}
\title[Decomposing Non-Redundant Sharing]
      {Decomposing Non-Redundant Sharing \\ by Complementation}
\author[E. Zaffanella, P. M. Hill and R. Bagnara]
       {ENEA ZAFFANELLA \\
       Department of Mathematics,
       University of Parma,
       Italy
       \email{zaffanella@cs.unipr.it}
       \and PATRICIA M. HILL\thanks{This work was partly supported
                                 by EPSRC under grant GR/M05645.} \\
       School of Computing,
       University of Leeds,
       Leeds, U.K.
       \email{hill@comp.leeds.ac.uk}
       \and ROBERTO BAGNARA\thanks{The work of the first and third authors
                          has been partly supported by MURST project
                          ``Certificazione automatica di programmi
                            mediante interpretazione astratta.''} \\
       Department of Mathematics,
       University of Parma,
       Italy
       \email{bagnara@cs.unipr.it}
}
\maketitle

\begin{abstract}
Complementation,
the inverse of the reduced product operation,
is a technique for systematically finding
minimal decompositions of abstract domains.
Fil\'e and Ranzato advanced the state of the art by introducing
a simple method for computing a complement.
As an application, they considered the  extraction by complementation
of the pair-sharing
domain $\PS$ from the Jacobs and Langen's set-sharing domain $\SH$.
However, since the result of this operation was still $\SH$, 
they concluded that $\PS$ was too abstract for this.
Here, we show that the source of this result lies not with $\PS$
but with $\SH$ and, more precisely, with the redundant
information contained in $\SH$
with respect to ground-dependencies and pair-sharing.
In fact, a proper decomposition is obtained
if the non-redundant version of $\SH$, $\PSD$,
is substituted for $\SH$.
To establish the results for $\PSD$, we define a general schema
for subdomains of $\SH$ that includes $\PSD$ and $\Def$ as special cases.
This sheds new light on the structure of $\PSD$
and exposes a natural though unexpected connection between $\Def$ and $\PSD$.
Moreover, we substantiate the claim
that complementation \emph{alone} is not sufficient
to obtain \emph{truly minimal} decompositions of domains.
The right solution to this problem is to \emph{first} remove redundancies
by computing the quotient of the domain with respect to
the observable behavior, and only \emph{then} decompose it by complementation.
\end{abstract}


\noindent {\bf Keywords:}
Abstract Interpretation,
Domain Decomposition,
Complementation,
Sharing Analysis.

\section{Introduction}

Complementation \cite{CortesiFGPR97}, which is
the inverse of the well-known reduced product operation \cite{CousotC79},
can systematically obtain minimal decompositions of complex abstract domains.
It has been argued that these decompositions would be useful
in finding space saving representations for
domains and to simplify domain verification problems.

In \cite{FileR96}, Fil\'e and Ranzato presented a new method for computing
the complement, which is simpler than the original proposal
by Cortesi \etal{} \cite{CortesiFGPR95,CortesiFGPR97}
because it has the advantage that,
in order to compute the complement, only a relatively small number of elements
(namely the \emph{meet-irreducible} elements of the
reference domain) need be considered.
As an application of this method, the authors considered the
Jacobs and Langen's sharing domain \cite{JacobsL92}, $\SH$,
for representing properties of variables such as
groundness and sharing.
This domain captures the property of set-sharing.
Fil\'e and Ranzato illustrated their method by minimally decomposing
$\SH$ into three components;
using the words of the authors
\cite[Section~1]{FileR96}:
\begin{quotation}
``[$\ldots$] each representing one of the elementary properties
that coexist in the elements of \textit{Sharing}, and that are as follows:
(i) the ground-dependency information;
(ii) the pair-sharing information, or equivalently variable independence;
(iii) the set-sharing information, without variable independence and
ground-dependency.''
\end{quotation}
However, this decomposition did not use the usual domain $\PS$
for pair-sharing.
Fil\'e and Ranzato observed that the complement
of the pair-sharing domain $\PS$
with respect to $\SH$ is again $\SH$
and concluded that $\PS$ was too abstract to be extracted from $\SH$
by means of complementation.
Thus, in order to obtain their non-trivial decomposition of $\SH$,
they used a different (and somewhat unnatural) definition
for an alternative pair-sharing domain, called $\PS'$.
The nature of $\PS'$ and its connection with $\PS$ is examined more
carefully in Section~\ref{sec:discussion}.

We noticed that the reason why Fil\'e and Ranzato obtained this result
was not to be found in the definition of $\PS$,
which accurately represents the property of pair-sharing,
but in the use of the domain $\SH$
to capture the property of pair-sharing.
In~\cite{BagnaraHZ97b,BagnaraHZ01TCS}, it was observed that, for most
(if not all) applications, the property of interest is not set-sharing
but pair-sharing.
Moreover, it was shown that, for groundness
and pair-sharing, $\SH$ includes redundant elements.
By defining an upper closure operator $\rho$ that removed this redundancy,
a much smaller domain $\PSD$,
which was denoted $\SHm$ in \cite{BagnaraHZ97b},
was found that captured pair-sharing and groundness
with the same precision as $\SH$.
We show here that using the method given in \cite{FileR96},
but with this domain instead of $\SH$ as the reference domain,
a proper decomposition can be obtained even when considering
the natural definition of the pair-sharing domain $\PS$.
Moreover, we show that $\PS$ is \emph{exactly} one of the components
obtained by complementation of $\PSD$.
Thus the problem exposed by Fil\'e and Ranzato was, in fact, due to the
``information preserving'' property of complementation,
as any factorization obtained in this way is such that the reduced product
of the factors gives back the original domain.
In particular, any factorization of $\SH$ has to encode the
redundant information identified
in~\cite{BagnaraHZ97b,BagnaraHZ01TCS}.
We will show that such a problem disappears
when $\PSD$ is used as the reference domain.

Although the primary purpose of this work is to clarify the
decomposition of the domain $\PSD$, the formulation is sufficiently general
to apply to other properties that are captured by $\SH$.
The domain $\Pos$ of positive Boolean functions and
its subdomain $\Def$, the domain of \emph{definite} Boolean functions,
are normally used for capturing
groundness~\cite{ArmstrongMSS98}.
Each Boolean variable has the value \emph{true}
if the program variable it corresponds to is definitely bound to a ground term.
However, the domain $\Pos$
is isomorphic to $\SH$ via the mapping from
formulas in $\Pos$ to the set of complements of their models~\cite{CodishS98}.
This means that any general result regarding the structure of $\SH$
is equally applicable to $\Pos$ and its subdomains.

To establish the results for $\PSD$, we define a general schema
for subdomains of
$\SH$ that includes $\PSD$ and $\Def$ as special cases.
This sheds new light on the structure of the domain $\PSD$,
which is smaller but significantly more
involved than $\SH$.\footnote{For the well acquainted with the matter:
$\SH$ is a powerset and hence it is dual-atomistic;
this is not the case for $\PSD$.}
Of course, as we have used the more general schematic approach, we can
immediately derive (where applicable) corresponding results
for $\Def$ and $\Pos$.
Moreover, an interesting consequence of this work is the discovery
of a natural connection between the abstract domains
$\Def$ and $\PSD$.
The results confirm that $\PSD$ is, in fact, the ``appropriate''
abstraction of the set-sharing domain $\SH$ that has to be considered
when groundness and pair-sharing are the properties of interest.

The paper, which is an extended version of \cite{ZaffanellaHB99},
is structured as follows:
In Section~\ref{sec:preliminaries} we briefly recall the required notions
and notations, even though we assume general acquaintance with the topics of
lattice theory, abstract interpretation,
sharing analysis and groundness analysis.
Section~\ref{sec:sharing-domains} introduces the $\SH$ domain
and several abstractions of it.
The meet-irreducible elements of an important family of abstractions
of $\SH$ are identified in Section~\ref{sec:meet-irreducible}.
This is required in order to apply, in Section~\ref{sec:decomposition},
the method of Fil\'e and Ranzato to this family.
In Section~\ref{sec:discussion} we present some final remarks and
we explain what is, in our opinion, the lesson to be learned from this and
other related work. Section~\ref{sec:conclusion} concludes.

\section{Preliminaries}
\label{sec:preliminaries}

For any set $S$, $\wp(S)$ denotes the power set of $S$
and $\card S$ is the cardinality of $S$.

A \emph{preorder} `$\preceq$' over a set $P$ is a binary relation that is
reflexive and transitive.
If `$\preceq$' is also antisymmetric, then it is called \emph{partial order}.
A set $P$ equipped with a partial order `$\preceq$' is said
to be \emph{partially ordered}
and sometimes written $\langle P, \preceq\rangle$.
Partially ordered sets are also called \emph{posets}.

A poset $\langle P, \preceq\rangle$ is \emph{totally ordered}
with respect to `$\preceq$' if, for each $x, y \in P$,
either $x \preceq y$ or $y \preceq x$.
A subset $S$ of a poset $\langle P, \preceq\rangle$
is a \emph{chain} if it is totally ordered
with respect to `$\preceq$'.

Given a poset $\langle P, \preceq\rangle$ and $S \sseq P$, $y \in P$ is
an \emph{upper bound} for $S$ if and only if $x \preceq y$ for each $x \in S$.
An upper bound $y$ for $S$ is a \emph{least upper bound} (or $\lub$)
of $S$ if and only if, for every upper bound $y'$ for $S$,
$y \preceq y'$.
The $\lub$, when it exists, is unique. In this case we write $y = \lub S$.
\emph{Lower bounds} and \emph{greatest lower bounds} (or $\glb$)
are defined dually.

A poset $\langle L, \preceq\rangle$ such that, for each $x, y \in L$,
both $\lub \{ x, y \}$ and $\glb \{ x, y \}$ exist, is called a
\emph{lattice}. In this case, $\lub$ and $\glb$ are also called, respectively,
the \emph{join} and the \emph{meet} operations of the lattice.
A \emph{complete lattice} is a lattice $\langle L, \preceq\rangle$
such that every subset of $L$ has both a least upper bound
and a greatest lower bound. The \emph{top} element of
a complete lattice $L$, denoted by $\top$, is such that
$\top \in L$ and $\forall x \in L \itc x \preceq \top$.
The \emph{bottom} element of $L$, denoted by $\bot$,
is defined dually.

As an alternative definition, a lattice is
an algebra $\langle L, \meet, \join \rangle$ such that
$\meet$ and $\join$ are two binary operations
over $L$ that are commutative, associative, idempotent, and satisfy the
following \emph{absorption laws}, for each $x, y \in L$:
$x \meet (x \join y) = x$ and
$x \join (x \meet y) = x$.

The two definitions of lattice are equivalent.
This can be seen by defining:
\[
  x \preceq y \quad\defiff\quad x \meet y = x \quad\defiff\quad x \join y = y
\]
and
\begin{align*}
  \glb \{ x, y \} &\defeq x \meet y, \\
  \lub \{ x, y \} &\defeq x \join y.
\end{align*}
The existence of an isomorphism between the two lattices
$L_1$ and $L_2$ is denoted by $L_1 \equiv L_2$.

A monotone and idempotent self-map $\fund{\rho}{P}{P}$
over a poset $\langle P, \preceq\rangle$ is
called a \emph{closure operator} (or \emph{upper closure operator})
if it is also \emph{extensive}, namely
\[
  \forall x \in P \itc x \preceq \rho(x).
\]
Each upper closure operator $\rho$ over a complete lattice $C$
is uniquely determined by the set of its fixpoints, that is, by
its image
\begin{align*}
  \rho(C)
    &\defeq
      \bigl\{\, \rho(x) \bigm| x \in C \,\bigr\}. \\
\intertext{%
We will often denote upper closure operators by their images.
The set of all upper closure operators over a complete lattice $C$,
denoted by $\uco(C)$, forms a complete lattice ordered as follows:
if $\rho_1, \rho_2 \in \uco(P)$,
$\rho_1 \sqsseq \rho_2$ if and only if $\rho_2(C) \sseq \rho_1(C)$.
The \emph{reduced product} of two elements $\rho_1$ and $\rho_2$
of $\uco(C)$ is denoted by $\rho_1 \ucomeet \rho_2$ and defined as
}
  \rho_1 \ucomeet \rho_2
    &\defeq
      \glb\{\rho_1,\rho_2\}.
\end{align*}
For a more detailed introduction to closure operators,
the reader is referred to \cite{GHK+80}.

A complete lattice $C$ is \emph{meet-continuous} if for any chain $Y \sseq C$
and each $x \in C$,
\[
  x \meet \bigl(\bigjoin Y\bigr) = \bigjoin_{y \in Y} (x \meet y).
\]
Most domains for abstract interpretation~\cite{CortesiFGPR97}
and, in particular, all the domains considered in this paper
are meet-continuous.

Assume that $C$ is a meet-continuous lattice.
Then the inverse of the reduced product operation, called
\emph{weak relative pseudo-complement},
is well defined and given as follows.
Let $\rho, \rho_1 \in \uco(C)$ be such that $\rho \sqsseq \rho_1$.
Then
\[
  \rho \sim \rho_1
    \defeq
      \lub\{\, \rho_2 \in \uco(C) \mid \rho_1 \ucomeet \rho_2 = \rho \,\}.
\]
Given $\rho \in \uco(C)$,
the \emph{weak pseudo-complement}
(or, by an abuse of terminology now customary in the field
of Abstract Interpretation, simply \emph{complement}) of $\rho$
is denoted by $\idc \sim \rho$, where $\idc$ is the identity over $C$.
Let $D_i \defeq \rho_{D_i}(C)$
with $\rho_{D_i} \in \uco(C)$ for $i = 1$, \dots,~$n$.
Then $\{\, D_i \mid 1\leq i\leq n \,\}$ is a \emph{decomposition for $C$}
if $C = D_1 \ucomeet \cdots \ucomeet D_n$.
The decomposition is also called \emph{minimal} if,
for each $k \in \Nset$ with $1 \leq k \leq n$
and each $E_k \in \uco(C)$,
$D_k \sqsslt E_k$ implies
\[
  C
    \sqsslt
      D_1 \ucomeet \cdots \ucomeet D_{k-1}
        \ucomeet E_k \ucomeet D_{k+1}
          \ucomeet \cdots \ucomeet D_n.
\]

Assume now that $C$ is a complete lattice.
If $X \sseq C$,
then $\Moore(X)$ denotes the \emph{Moore completion of $X$},
namely,
\[
  \Moore(X) \defeq \bigl\{\, \bigwedge Y \bigm| Y \sseq X \,\bigm\}.
\]
We say that \emph{$C$ is meet-generated by $X$} if $C = \Moore(X)$.
An element $x \in C$ is \emph{meet-irreducible} if
\[
  \forall y, z \in C
    \itc \bigl((x = y \meet z) \implies (x = y \text{ or } x = z)\bigr).
\]
The set of meet-irreducible elements of a
complete lattice $C$ is denoted by $\MI(C)$.
Note that $\top \in \MI(C)$.
An element $x \in C$ is a \emph{dual-atom} if $x \neq \top$ and,
for each $y \in C$, $x \leq y < \top$ implies $x = y$.
The set of dual-atoms is denoted by $\dAtoms(C)$.
Note that $\dAtoms(C) \sslt \MI(C)$.
The domain $C$ is \emph{dual-atomistic} if $C = \Moore\bigl(\dAtoms(C)\bigr)$.
Thus, if $C$ is dual-atomistic,
$\MI(C) = \{\top\} \union \dAtoms(C)$.
The following result
holds~\cite[Theorem~4.1]{FileR96}.
\begin{thm}
\label{thm:FileR96}
If $C$ is meet-generated by $\MI(C)$ then $\uco(C)$ is
pseudo-com\-ple\-mented and for any $\rho \in  \uco(C)$
\[
  \idc \sim \rho = \Moore\bigl(\MI(C) \setdiff \rho(C)\bigr).
\]
\end{thm}
Another interesting result is the following
\cite[Corollary~4.5]{FileR96}.
\begin{thm}
\label{thm: dual-atoms}
If $C$ is dual-atomistic then $\uco(C)$ is pseudo-complemented
and for any $\rho \in \uco(C)$
\[
  \idc \sim \rho = \Moore\bigl(\dAtoms(C) \setdiff \rho(C)\bigr).
\]
\end{thm}

Let $\Vars$ be a denumerable set of variables.
For any syntactic object $o$, $\vars(o)$ denotes
the set of variables occurring in $o$.
Let $\Terms$ be the set of first-order terms over $\Vars$.
If $x \in \Vars$ and $t \in \Terms \setdiff \{ x \}$,
then $x \mapsto t$ is called a \emph{binding}.
A \emph{substitution} is a total function $\fund{\sigma}{\Vars}{\Terms}$
that is the identity almost everywhere.
Substitutions are denoted by the set of their bindings,
thus a substitution $\sigma$ is identified with the (finite) set
\[
  \bigl\{\, x \mapsto \sigma(x) \bigm| x \neq \sigma(x) \,\bigr\}.
\]
If $t \in \Terms$, we write $t \sigma$ to denote $\sigma(t)$.
A substitution $\sigma$ is \emph{idempotent} if, for all $t\in\Terms$,
we have $t\sigma\sigma=t\sigma$. The set of all idempotent substitutions
is denoted by $\Subst$.

It should be stressed that this restriction to idempotent substitutions
is provided for presentation purposes only.
In particular, it allows for a straight comparison of our work
with respect to other works appeared in the literature.
However, the results proved in this paper do not rely on the idempotency
of substitutions and are therefore applicable also when considering
substitutions in \emph{rational solved form} \cite{Colmerauer82,Colmerauer84}.
Indeed, we have proved in \cite{HillBZ98b} that
the usual abstract operations defined on the domain $\SH$,
approximating concrete unification over finite trees,
also provide a correct approximation of concrete unification
over a domain of rational trees.


\section{The \textsf{Sharing} Domains}
\label{sec:sharing-domains}

In order to provide a concrete meaning to the elements of the set-sharing
domain of D.~Jacobs and A.~Langen~\cite{JacobsL89,Langen90th,JacobsL92},
a knowledge of the finite set $\VI \sslt \Vars$ of variables of interest
is required.
For example, in the Ph.D.~thesis of Langen~\cite{Langen90th} this set
is implicitly defined, for each clause being analyzed, as the finite set
of variables occurring in that clause.
A clearer approach has been introduced in~\cite{CortesiFW94,CortesiFW98}
and also adopted in~\cite{BagnaraHZ97b,BagnaraHZ01TCS,CortesiF99},
where the set of variables of interest is given explicitly
as a component of the abstract domain.
During the analysis process, this set is \emph{elastic}.
That is, it expands (e.g., when solving clause's bodies)
and contracts (e.g., when abstract descriptions are projected
onto the variables occurring in clause's heads).
This technique has two advantages: 
first, a clear and unambiguous description of those semantic operators
that modify the set of variables of interest is provided;
second, the definition of the abstract domain is completely independent
from the particular program being analyzed.
However, since at any given time the set of variables of interest is fixed,
we can simplify the presentation by consistently denoting this set by $\VI$.
Therefore, in this paper all the abstract domains defined are restricted
to a fixed set of variables of interest $\VI$ of finite cardinality $n$;
this set is not included explicitly in the representation
of the domain elements;
also, when considering abstract semantic operators having some arguments
in $\Subst$, such as the abstract $\mgu$, the considered substitutions
are always taken to have variables in $\VI$.
We would like to emphasize that
this is done for ease of presentation only:
the complete definition of both the domains and the semantic operators
can be immediately derived from those given, e.g.,
in~\cite{BagnaraHZ97b,BagnaraHZ01TCS}.
Note that other solutions are possible; we refer the interested reader
to~\cite[Section~7]{CortesiFW96}
and~\cite[Section~10]{Scozzari01TCS},
where this problem is discussed in the context of groundness analysis.

\subsection{The Set-sharing Domain $\SH$}

\begin{defn} \summary{(The \emph{set-sharing} domain $\SH$.)}
The domain $\SH$ is given by
\begin{align*}
 \SH &\defeq \wp(\SG), \\
\intertext{%
where the set of \emph{sharing-groups} $\SG$ is given by
}
  \SG
    &\defeq
      \wp(\VI) \setdiff \{ \emptyset \}.
\end{align*}
$\SH$ is partially ordered by set inclusion so that
the $\lub$ is given by set union and the $\glb$ by set intersection.
\end{defn}
Note that, as we are adopting the upper closure operator approach to
abstract interpretation, all the domains we define here
are ordered by subset inclusion.
As usual in the field of abstract interpretation,
this ordering provides a formalization of precision
where the less precise domain elements are those occurring higher
in the partial order.
Thus, more precise elements contain less sharing groups.

Since $\SH$ is a power set, $\SH$ is dual-atomistic and
\[
  \dAtoms(\SH)
    =
      \bigl\{\,
        \SG \setdiff \{S\}
      \bigm|
         S \in \SG
      \,\bigr\}.
\]

In all the examples in this paper, the elements of $\SH$
are written in a simplified notation, omitting the inner braces.
For instance, the set
\[
  \bigl\{ \{x\}, \{x,y\}, \{x,z\}, \{x,y,z\}\bigr\}
\]
would be written simply as
\[
   \{ x, xy, xz, xyz \}.
\]

\begin{exmp}
\label{ex: three-vars-datoms}
Suppose $\VI = \{ x, y, z \}$.
Then the seven dual-atoms of $\SH$ are:
\begin{align*}
  &\left.
    \begin{aligned}
      s_1 &= \{\phantom{x,{}} y,z,xy,xz,yz,xyz\},\\
      s_2 &= \{x,\phantom{y,{}} z,xy,xz,yz,xyz\},\\
      s_3 &= \{x,y,\phantom{z,{}} xy,xz,yz,xyz\},
    \end{aligned}
  \right\} &&\text{ these lack a singleton}; \\
  &\left.
    \begin{aligned}
      s_4 &= \{x,y,z,\phantom{xy,{}} xz,yz,xyz\},\\
      s_5 &= \{x,y,z,xy,\phantom{xz,{}} yz,xyz\},\\
      s_6 &= \{x,y,z,xy,xz,\phantom{yz,{}} xyz\},\\
    \end{aligned}
  \right\} &&\text{ these lack a pair}; \\
  &\left.
    \begin{aligned}
      s_7 &= \{x,y,z,xy,xz,yz\phantom{{},xyz}\},
    \end{aligned}
  \right.  &&\text{ this lacks $\VI$.}
\end{align*}
\end{exmp}
The meet-irreducible elements of $\SH$ are
$s_1$,\dots,~$s_7$, and the top element $\SG$.

\begin{defn} \summary{(Operations over $\SH$.)}
\label{def:abs-funcs}
The function
$\fund{\bin}{\SH\times\SH}{\SH}$,
called \emph{binary union},
is given, for each $\sh_1, \sh_2 \in \SH$, by
\begin{align*}
  \bin(\sh_1, \sh_2)
    &\defeq
      \{\,
        S_1 \union S_2
      \mid
        S_1 \in \sh_1,
        S_2 \in \sh_2
      \,\}. \\
\intertext{%
The \emph{star-union}  function
$\fund{(\cdot)^\star}{\SH}{\SH}$
is given,
for each $\sh \in \SH$,
by
}
  \sh^\star
    &\defeq
      \Bigl\{\,
        S \in \SG
      \Bigm|
            \exists \sh' \sseq \sh
              \st S = \bigunion \sh'
      \,\Bigr\}.\\
\intertext{%
The \emph{$j$-self-union} function $\fund{(\cdot)^j}{\SH}{\SH}$ is given,
for each $j \geq 1$ and $\sh \in \SH$,
by
}
  \sh^j
    &\defeq
      \Bigl\{\,
        S \in \SG
      \Bigm|
        \exists \sh' \sseq \sh
          \st \Bigl(\card \sh' \leq j, S = \bigunion \sh'\Bigr)
      \,\Bigr\}. \\
\intertext{%
The extraction of the
\emph{relevant component} of an element of $\SH$
with respect to a subset of $\VI$
is encoded by the function
$\fund{\rel}{\wp(\VI)\times\SH}{\SH}$
given, for each $V \sseq \VI$ and each $\sh \in \SH$, by
}
  \rel(V, \sh)
    &\defeq
      \{\, S \in \sh \mid S \inters V \neq \emptyset \,\}.\\
\intertext{%
The function $\amgu$ captures the effects of a binding $x \mapsto t$
on an element of $\SH$.
Let $\sh \in \SH$,
$v_x = \{x\}$, $v_t = \vars(t)$, and $v_{xt} = v_x \union v_t$.
Then
}
  \amgu(\sh, x \mapsto t)
    &\defeq
      \bigl(\sh \setdiff (\rel(v_{xt},\sh)\bigr)
        \union \bin\bigl(\rel(v_x,\sh)^\star, \rel(v_t,\sh)^\star\bigr). \\
\intertext{%
  We also define the extension
  \(
    \fund{\amgu}{\SH\times\Subst}{\SH}
  \)
  by
}
  \amgu(\sh, \emptyset)
    &\defeq
      \sh, \\
  \amgu\bigl(\sh, \{x \mapsto t\} \union \sigma\bigr)
    &\defeq
      \amgu\bigl(\amgu(\sh, x \mapsto t),
                 \sigma \setdiff \{x \mapsto t\}\bigr).\\
\intertext{%
The function $\fund{\proj}{\SH\times\wp(\VI)}{\SH}$
that \emph{projects} an element of $\SH$ onto a subset $V \sseq \VI$
of the variables of interest is given, for each $\sh \in \SH$, by
}
  \proj(\sh, V)
    &\defeq
      \{\, S \inters V \mid S \in \sh, S \inters V \neq \emptyset \,\}
      \union
      \bigl\{\, \{ x \} \bigm| x \in \VI \setdiff V \,\bigr\}.
\end{align*}
\end{defn}

Together with $\lub$, the functions $\proj$ and $\amgu$ 
are the key operations that make the abstract domain $\SH$
suitable for computing static approximations of
the substitutions generated by the execution of logic programs.
These operators can be combined with simpler ones
(e.g., consistent renaming of variables)
so as to provide a complete definition of the abstract semantics.
Also note that these three operators have been proved to be
the \emph{optimal approximations}
of the corresponding concrete operators~\cite{CortesiF99}.
The $j$-self-union operator defined above is new. 
We show later when it 
may safely replace the star-union operator.
Note that, letting $j = 1$, $2$, and~$n$, we have
$\sh^1 = \sh$, $\sh^2 = \bin(\sh,\sh)$,
and, as $\card \VI = n$, $\sh^n = \sh^\star$.

\subsection{The Tuple-Sharing Domains}

To provide a general characterization of domains such as the groundness and
pair-sharing domains contained in $\SH$,
we first identify the sets of elements that have the same cardinality.

\pagebreak
\begin{defn} \summary{(Tuples of cardinality $k$.)}
For each $k \in \Nset$ with $1\leq k \leq n$, the overloaded functions
$\fund{\tuples_k}{\SG}{\SH}$ and
$\fund{\tuples_k}{\SH}{\SH}$
are defined as
\begin{align*}
  \tuples_k(S)
    &\defeq
      \bigl\{\,
        T \in \wp(S)
      \bigm|
        \card T =k
      \,\bigr\}, \\
  \tuples_k(\sh)
    &\defeq
      \bigunion
        \bigl\{\,
          \tuples_k(S')
        \bigm|
           S' \in \sh
        \,\bigr\}. \\
\intertext{%
In particular, if $S \in \SG$ and $\sh \in\SH$, let
}
  \pairs(S) &\defeq \tuples_2(S),\\
  \pairs(\sh) &\defeq \tuples_2(\sh).
\end{align*}
\end{defn}

The usual domains that represent groundness and pair-sharing information
will be shown to be special cases of the following more general domain.

\begin{defn} \summary{(The \emph{tuple-sharing} domains $\TSk$.)}
\label{def: tuple-domain}
For each $k \in \Nset$ such that $1\leq k \leq n$,
the function $\fund{\rhoTSk}{\SH}{\SH}$ is
defined as
\begin{align*}
  \rhoTSk(\sh)
    &\defeq
      \bigl\{\,
        S \in \SG
      \bigm|
        \tuples_k(S) \sseq \tuples_k(\sh)
      \,\bigr\} \\
\intertext{%
and, as $\rhoTSk \in\uco(\SH)$, it induces the lattice
}
  \TSk &\defeq  \rhoTSk(\SH).
\end{align*}
\end{defn}
Note that $\rhoTSk\bigl(\tuples_k(\sh)\bigr) = \rhoTSk(\sh)$ and that there
is a one to one correspondence between $\TSk$ and
$\wp\bigl(\tuples_k(\VI)\bigr)$.
The isomorphism is given by the functions
$\fund{\tuples_k}{\TSk}{\wp\bigl(\tuples_k(\VI)\bigr)}$ and
$\fund{\rhoTSk}{\wp\bigl(\tuples_k(\VI)\bigr)}{\TSk}$.
Thus the domain $\TSk$ is the smallest domain
that can represent properties characterized by sets of variables of
cardinality $k$.
We now consider the tuple-sharing domains
for the cases when $k=1$, $2$, and~$n$.
\begin{defn} \summary{(The \emph{groundness} domain $\Con$.)}
The upper closure operator $\fund{\rhoCon}{\SH}{\SH}$
and the corresponding domain $\Con$ are defined as
\begin{align*}
  \rhoCon
    &\defeq \rhoTSone, \\
  \Con
    &\defeq
      \TSone(\SH) = \rhoCon(\SH).
\end{align*}
\end{defn}
This domain, which represents groundness information,
is isomorphic to a domain of conjunctions of Boolean variables.
The isomorphism $\tuples_1$ maps each element of
$\Con$ to the set of variables that are possibly non-ground.
From the domain $\tuples_1(\Con)$, by set complementation,
we obtain the classical domain $\JonesSondG$~\cite{JonesS87}
for representing the set of variables that are definitely ground
(so that we have $\TSone \defeq \Con \equiv \JonesSondG$).

\pagebreak
\begin{defn} \summary{(The \emph{pair-sharing} domain $\PS$.)}
The upper closure operator $\fund{\rhoPS}{\SH}{\SH}$
and the corresponding domain $\PS$ are defined as
\begin{align*}
  \rhoPS
    &\defeq \rhoTStwo, \\
  \PS
    &\defeq
      \TStwo(\SH) = \rhoPS(\SH).
\end{align*}
\end{defn}
This domain represents
pair-sharing information and the isomorphism $\tuples_2$ maps each element of
$\PS$ to the set of pairs of variables that may be
bound to terms that share a common variable.
The domain for representing variable independence
can be obtained by set complementation.

Finally, in the case when $k=n$ we have a domain consisting of just
two elements:
\[
  \TSn = \bigl\{ \SG, \SG \setdiff \{\VI\} \bigr\}.
\]
Note that the bottom of $\TSn$ differs from the top element $\SG$
only in that it lacks the sharing group $\VI$.
There is no intuitive reading for the information encoded by this
element: it describes all but those substitutions $\sigma \in \Subst$
such that
\(
  \biginters
    \bigl\{\,
      \vars(x\sigma)
    \bigm|
      x \in \VI
    \,\bigr\}
      \neq \emptyset
\).

Just as for $\SH$, the domain $\TSk$ (where $1 \leq k \leq n$)
is dual-atomistic and:
\begin{align*}
 \dAtoms(\TSk) &=
  \Bigl\{\,
    \bigl( \SG \setdiff \{\, U \in \SG \mid T \sseq U\,\} \bigr)
  \Bigm|
    T \in \tuples_k(\VI)
  \,\Bigr\}.\\
\intertext{%
Thus we have
}
\dAtoms(\Con) &=
  \Bigl\{\,
    \bigl( \SG \setdiff \{\, U \in \SG \mid x \in U\,\} \bigr)
  \Bigm|
    x\in \VI
  \,\Bigr\},\\
\dAtoms(\PS) &=
  \Bigl\{\,
    \bigl( \SG \setdiff \{\, U \in \SG \mid x,y \in U\,\} \bigr)
  \Bigm|
    x, y \in \VI, x \neq y
  \,\Bigr\}.
\end{align*}

\begin{exmp}
\label{ex: Con-PS-datoms}
Consider Example~\ref{ex: three-vars-datoms}.
Then the dual-atoms of $\Con$ are
\begin{align*}
      r_1 =  s_1 \inters s_4 \inters s_5 \inters s_7
          &= \{\phantom{x,{}} y,z,\phantom{xy,{}} \phantom{xz,{}} yz\},\\
      r_2 =  s_2 \inters s_4 \inters s_6 \inters s_7
          &= \{x, \phantom{y,{}} z,\phantom{xy,{}} xz \phantom{,{}yz}\},\\
      r_3 =  s_3 \inters s_5 \inters s_6 \inters s_7
          &= \{x,y, \phantom{z,{}} xy \phantom{,{}xz} \phantom{,{}yz}\};\\
\intertext{%
the dual-atoms of $\PS$ are
}
      m_1 =  s_4 \inters s_7
          &= \{x,y,z,\phantom{xy,{}} xz, yz\},\\
      m_2 =  s_5 \inters s_7
          &= \{x,y,z,xy,  \phantom{xz,{}} yz\},\\
      m_3 =  s_6 \inters s_7
          &= \{x,y,z, xy, xz \phantom{,{}yz}\}.
\end{align*}
\end{exmp}

It can be seen from the dual-atoms that,
for each $j = 1$, \dots,~$n$, where $j \neq k$,
the precision of the information encoded by domains
$\TSj$ and $\TSk$ is not comparable.
Also, we note that, if $j<k$, then $\rhoTSj(\TSk) = \{\SG\}$
and  $\rhoTSk(\TSj) = \TSj$.

\subsection{The Tuple-Sharing Dependency Domains}

We now need to define domains that capture the propagation of
groundness and pair-sharing; in particular,
the dependency of these properties on the further
instantiation of the variables.
In the same way as with $\TSk$ for $\Con$
and $\PS$, we first define a general subdomain $\TSDk$ of $\SH$.
This must be safe with respect to the tuple-sharing property
represented by $\TSk$ when performing the usual abstract operations.
This was the motivation behind the introduction
in~\cite{BagnaraHZ97b,BagnaraHZ01TCS}
of the pair-sharing dependency domain $\PSD$.
We now generalize this for tuple-sharing.

\begin{defn} \summary{The \emph{tuple-sharing dependency} domain ($\TSDk$.)}
\label{def:rhoSTk}
For each $k$ where $1\leq k \leq n$,
the function $\fund{\rhoTSDk}{\SH}{\SH}$ is defined as
\begin{multline*}
  \rhoTSDk(\sh) \\
    \defeq
        \Bigl\{\,
          S \in \SG
        \Bigm|
          \forall T \sseq S
            \itc \card T <k
              \implies
                S = \bigunion \{\,
                                U \in \sh
                              \mid
                                T \sseq U \sseq S
                              \,\}
        \,\Bigr\},
\end{multline*}
and, as $\rhoTSDk \in\uco(\SH)$,
it induces the \emph{tuple-sharing dependency} lattice
\[
  \TSDk \defeq  \rhoTSDk(\SH).
\]
\end{defn}
It follows from the definitions that the domains $\TSDk$ form a strict chain.
\begin{prop}
\label{prop:TSDk-chain}
For $j, k \in \Nset$ with $1\leq j < k \leq n$, we have
\(
  \TSDj \sslt \TSDk.
\)
\end{prop}
Moreover, $\TSDk$ is not less precise than $\TSk$.
\begin{prop}
\label{prop:TSDk-vs-TSk}
For $k \in \Nset$ with $1\leq k \leq n$, we have
\(
  \TSk \sseq \TSDk.
\)
Furthermore, if $n > 1$ then
\(
  \TSk \sslt \TSDk.
\)
\end{prop}
As an immediate consequence
of Propositions~\ref{prop:TSDk-chain} and~\ref{prop:TSDk-vs-TSk}
we have that that $\TSDk$ is not less precise than
$\TSone \ucomeet \cdots \ucomeet \TSk$.
\begin{cor}
\label{cor:TSDk-vs-TSj}
For $j, k \in \Nset$ with $1 \leq j \leq k \leq n$, we have
\(
  \TSj \sseq \TSDk.
\)
\end{cor}
It also follows from the definitions that, for the $\TSDk$ domain,
the star-union operator can be replaced by the $k$-self-union operator.
\begin{prop}
\label{pro: k-self-union}
For $1\leq k \leq n$, we have
\(
  \rhoTSDk\bigl(\sh^k\bigr) = \sh^\star.
\)
\end{prop}

We now instantiate the tuple-sharing dependency domains
for the cases when $k=1$, $2$, and~$n$.

\pagebreak
\begin{defn} \summary{(The \emph{ground dependency} domain $\Def$.)}
The domain $\Def$ is induced by the upper closure operator
$\fund{\rhoDef}{\SH}{\SH}$.
They are defined as
\begin{align*}
  \rhoDef
    &\defeq \rhoTSDone, \\
  \Def
    &\defeq
        \TSDone =  \rhoDef(\SH).
\end{align*}
\end{defn}
By Proposition~\ref{pro: k-self-union}, we have, for all $\sh \in \SH$,
$\rhoTSDone(\sh) = \sh^\star$ so that
$\TSDone$ is a representation of the domain $\Def$
used for capturing groundness.
It also provides evidence for the fact that the computation of the star-union
is not needed for the elements in $\Def$.
\begin{defn} \summary{(The \emph{pair-sharing dependency} domain $\PSD$.)}
The upper closure operator $\fund{\rhoPSD}{\SH}{\SH}$
and the corresponding domain $\PSD$ are defined as
\begin{align*}
  \rhoPSD
    &\defeq \rhoTSDtwo, \\
  \PSD
    &\defeq
        \TSDtwo =  \rhoPSD(\SH).
\end{align*}
\end{defn}
Then, it follows
from~\cite[Theorem~7]{BagnaraHZ97b}
that $\PSD$ corresponds to the domain $\SHm$
defined for capturing pair-sharing.
By Proposition~\ref{pro: k-self-union} we have, for all $\sh \in \SH$,
that $\rhoPSD(\sh^2) = \sh^\star$,
so that, for elements in $\PSD$,
the star-union operator $\sh^\star$ can be replaced by the
$2$-self-union $\sh^2 = \bin(\sh, \sh)$ without any loss of precision.
This was also proved in~\cite[Theorem~11]{BagnaraHZ97b}.
Furthermore, Corollary~\ref{cor:TSDk-vs-TSj} confirms the observation
made in~\cite{BagnaraHZ97b}
that $\PSD$ also captures groundness.

Finally, letting $k=n$, we observe that $\TSDn = \SH$.
Figure~\ref{fig:relations-between-sharing-domains} summarizes
the relations between the tuple-sharing and the tuple-sharing dependency
domains.

\begin{figure}
\def\objectstyle{\displaystyle}
\xymatrix@!C=1cm@!R=1cm{
  \TSone = \Con & \TStwo = \PS & \TS_3 \ar@{.}[rr] & & \TS_{n-1} & \TSn \\
  & \bigucomeet_{i=1}^2 \TSi \ar@{-}[ul] \ar@{-}[u] \\
  \TSDone = \Def \ar@{-}[uu] & & \bigucomeet_{i=1}^3 \TSi \ar@{-}[ul] \ar@{-}[uu] \\
  & \TSDtwo = \PSD \ar@{-}[uu] \ar@{-}[ul] \\
  & & \TSD_3 \ar@{-}[uu] \ar@{-}[ul] & & \bigucomeet_{i=1}^{n-1} \TSi \ar@{-}[uuuu] \ar@{.}[ulul] \\
  & & & & & \\
  & & & & \TSD_{n-1} \ar@{-}[uu] \ar@{.}[ulul] \\
  & & & & & \TSDn = \bigucomeet_{i=1}^n \TSi = \SH \ar@{-}[uuuuuuu] \ar@{-}[ul] \ar@{-}[uuul] \\
}
\caption{The set-sharing domain $\SH$ and some of its abstractions.}
\label{fig:relations-between-sharing-domains}
\end{figure}

As already discussed at the start of this section,
the set of variables of interest $\VI$ is fixed and, to simplify
the notation, omitted.
In~\cite{BagnaraHZ97b,BagnaraHZ01TCS} the domains $\SSl$ and $\SSm$
(corresponding to $\SH$ and $\PSD$, respectively)
are instead obtained by explicitly adding to each domain element
a new component, representing the set of variables of interest.
It is shown that $\SSm$ is as good as $\SSl$ for both representing and
propagating pair-sharing and it is also proved that any weaker domain
does not satisfy these properties,
so that $\SSm$ is the quotient \cite{CortesiFW94,CortesiFW98} of $\SSl$
with respect to the pair-sharing property $\PS$.

We now generalize and strengthen the results
in~\cite{BagnaraHZ97b,BagnaraHZ01TCS}
and show that, for each $k \in \{1,\ldots,n\}$,
$\TSDk$ is the quotient of $\SH$
with respect to the reduced product $\TSone \ucomeet \cdots \ucomeet \TSk$.
These results are proved at the end of this section.
\begin{thm}
\label{thm: no-loss-ops}
Let $\sh_1, \sh_2 \in \SH$ and $1\leq k \leq n$.
If $\rhoTSDk(\sh_1) = \rhoTSDk(\sh_2)$ then,
for each $\sigma \in \Subst$, each $\sh' \in \SH$,
and each $V \in \wp(\VI)$,
\begin{align*}
     \rhoTSDk\bigl(\amgu(\sh_1, \sigma)\bigr)
  &= \rhoTSDk\bigl(\amgu(\sh_2, \sigma)\bigr), \\
%
     \rhoTSDk(\sh' \union \sh_1)
  &= \rhoTSDk(\sh' \union \sh_2), \\
%
     \rhoTSDk\bigl(\proj(\sh_1, V)\bigr)
  &= \rhoTSDk\bigl(\proj(\sh_2, V)\bigr).
\end{align*}
\end{thm}

\begin{thm}
\label{thm: smallest-domain-for-ops}
Let $1\leq k \leq n$
For each $\sh_1, \sh_2 \in \SH$,
$\rhoTSDk(\sh_1) \neq \rhoTSDk(\sh_2)$
implies
\[
    \exists \sigma \in \Subst, \exists j \in \{1,\ldots,k\} \st
      \rhoTSj\bigl(\amgu(\sh_1, \sigma)\bigr)
        \neq \rhoTSj\bigl(\amgu(\sh_2,\sigma)\bigr).
\]
\end{thm}

\subsection{Proofs of Theorems~\ref{thm: no-loss-ops}
and~\ref{thm: smallest-domain-for-ops}}

In what follows we use the fact that
$\rhoTSDk$ is an upper closure operator so that,
for each $\sh_1, \sh_2 \in \SH$,
\begin{align}
\label{eq-emi-rho}
  \sh_1 \sseq \rhoTSDk(\sh_2)
    &\iff
      \rhoTSDk(\sh_1) \sseq \rhoTSDk(\sh_2). \\
\intertext{%
In particular, since $ (\cdot)^\star = \rhoTSDone$, we have
}
\label{eq-emi-star}
  \sh_1 \sseq \sh_2^\star
    &\iff
      \sh_1^\star \sseq \sh_2^\star.
\end{align}

\begin{lem}
\label{lem:addit}
For each $\sh \in \SH$ and each $V \in \wp(\VI)$,
\[
  \rhoTSDk(\sh) \setdiff \rel\bigl(V, \rhoTSDk(\sh)\bigr)
    = \rhoTSDk\bigl(\sh \setdiff \rel(V,\sh)\bigr).
\]
\end{lem}
\begin{proof*}
By Definition~\ref{def:rhoSTk},
\begin{align*}
  S \in &\rhoTSDk\bigl(\sh \setdiff \rel(V, \sh)\bigr) \\
    &\iff
      \forall T \sseq S
        \itc
          \Bigl(
            \card T < k
              \implies
                S = \bigunion \bigl\{\,
                                U \in \sh \setdiff \rel(V, \sh)
                              \bigm|
                                T \sseq U \sseq S
                              \,\bigr\}
          \Bigr) \\
    &\iff
      \forall T \sseq S
        \itc
          \Bigl(
            \card T < k
              \implies
                S = \bigunion \{\,
                                U \in \sh
                              \mid
                                T \sseq U \sseq S
                              \,\}
          \Bigr) \\
    &\qquad\qquad
                \land S \inters V = \emptyset \\
    &\iff
  S \in \rhoTSDk(\sh) \setdiff \rel\bigl(V, \rhoTSDk(\sh)\bigr). \mathproofbox
\end{align*}
\end{proof*}

\begin{lem}
\label{lem:rho-inclusion-implies-rel-star-inclusion}
For each $\sh_1, \sh_2 \in \SH$, each $V \in \wp(\VI)$
and each $k \in \Nset$ with $1 < k \leq n$,
\[
  \rhoTSDk(\sh_1) \sseq \rhoTSDk(\sh_2)
    \implies
      \rel(V, \sh_1)^\star \sseq \rel(V,\sh_2)^\star.
\]
\end{lem}
\begin{proof}
We prove that
\[
  \sh_1 \sseq \rhoTSDk(\sh_2)
    \implies
      \rel(V,\sh_1) \sseq \rel(V,\sh_2)^\star.
\]
The result then follows from Eqs.~(\ref{eq-emi-rho}) and~(\ref{eq-emi-star}).

Suppose $S \in \rel(V, \sh_1)$.
Then, $S \in \sh_1$ and $V \inters S \neq \emptyset$.
By the hypothesis, $S \in \rhoTSDk(\sh_2)$.
Let $x \in V \inters S$.
Then, by Definition \ref{def:rhoSTk}, we have
\begin{align*}
  S &= \bigunion
         \bigl\{\,
           U \in \sh_2
         \bigm|
           \{x\} \sseq U \sseq S
         \,\bigr\} \\
    &= \bigunion
         \bigl\{\,
           U \in \rel(V, \sh_2)
         \bigm|
           \{x\} \sseq U \sseq S
         \,\bigr\}.
\end{align*}
Thus $S \in \rel(V, \sh_2)^\star$.
\end{proof}

\begin{lem}
\label{lem:rho-equiv-implies-amgu-cong}
For each $\sh_1, \sh_2 \in \SH$, each $\sigma \in \Subst$
and each $k \in \Nset$ with $1 \leq k \leq n$,
\[
  \rhoTSDk(\sh_1) = \rhoTSDk(\sh_2)
    \implies
      \rhoTSDk\Bigl(\amgu\bigl(\sh_1, \sigma\bigr)\Bigr)
        = \rhoTSDk\Bigl(\amgu\bigl(\sh_2, \sigma\bigr)\Bigr).
\]
\end{lem}
\pagebreak
\begin{proof}
If $\sigma = \emptyset$, the statement is obvious from the definition
of $\amgu$.
In the other cases, the proof is by induction on the size of $\sigma$.
The inductive step, when $\sigma$ has more than one binding,
is straightforward.
For the base case, when $\sigma = \{ x \mapsto t \}$,
we have to show that
\[
  \sh_1 \sseq \rhoTSDk(\sh_2)
    \implies
      \amgu\bigl(\sh_1, \{x \mapsto t\}\bigr)
        \sseq \rhoTSDk\Bigl(\amgu\bigl(\sh_2, \{x \mapsto t\}\bigr)\Bigr).
\]
The result then follows from Eq.~(\ref{eq-emi-rho}).

Let $v_x \defeq \{x\}$, $v_t \defeq \vars(t)$,
and $v_{xt} \defeq v_x \union v_t$.
Suppose
\[
  S \in \amgu\bigl(\sh_1, \{x \mapsto t\}\bigr).
\]
Then, by definition of $\amgu$,
\[
  S \in \bigl(\sh_1 \setdiff \rel(v_x \union v_t, \sh_1)\bigr)
    \union
      \bin\bigl(\rel(v_x, \sh_1)^\star,
                \rel(v_t, \sh_1)^\star\bigr).
\]
There are two cases:
\begin{enumerate}
\item[1.]
\(
  S \in \sh_1 \setdiff \rel(v_x \union v_t, \sh_1)
\).
Then, by hypothesis, $S \in\rhoTSDk(\sh_2)$.
Hence we have
$S \in \rhoTSDk(\sh_2) \setdiff \rel\bigl(v_x \union v_t,\rhoTSDk(\sh_2)\bigr)$.
Thus, by Lemma~\ref{lem:addit},
\[
  S \in \rhoTSDk\bigl(\sh_2 \setdiff \rel(v_x \union v_t, \sh_2)\bigr).
\]
\item[2.]
\(
  S \in \bin\bigl(\rel(v_x, \sh_1)^\star,
                  \rel(v_t, \sh_1)^\star\bigr)
\).
Then we must have $S = T \union R$ where
$T \in \rel(v_x, \sh_1)^\star$ and
$R \in \rel(v_t, \sh_1)^\star$.
\end{enumerate}

The proof here splits into two branches, 2a and 2b, 
depending on whether $k> 1$ or $k=1$.
\begin{enumerate}
\item[2a.]
We first assume that $k > 1$.
Then, by Lemma~\ref{lem:rho-inclusion-implies-rel-star-inclusion} we have that
$T \in \rel(v_x, \sh_2)^\star$ and
$R \in \rel(v_t, \sh_2)^\star$.
Hence,
\[
  S \in \bin\bigl(\rel(v_x, \sh_2)^\star,
                  \rel(v_t, \sh_2)^\star\bigr).
\]
\end{enumerate}

Combining case~1 and case~2a we obtain
\[
  S \in \rhoTSDk\bigl(\sh_2 \setdiff \rel(v_x \union v_t, \sh_2)\bigr)
    \union  \bin\bigl(\rel(v_x, \sh_2)^\star,
                      \rel(v_t, \sh_2)^\star\bigr).
\]
Hence as $\rhoTSDk$ is extensive and monotonic
\[
  S \in \rhoTSDk\Bigl(\bigl(\sh_2 \setdiff \rel(v_x \union v_t, \sh_2)\bigr)
    \union \bin\bigl(\rel(v_x, \sh_2)^\star,
                     \rel(v_t, \sh_2)^\star\bigr)\Bigr),
\]
and hence, when $k>1$,
$S \in \rhoTSDk\Bigl(\amgu\bigl(\sh_2, \{x \mapsto t\}\bigr)\Bigr)$.

\begin{enumerate}
\item[2b.]
Secondly suppose that $k=1$.
In this case, we have,  by Proposition~\ref{pro: k-self-union}:
 \begin{align*}
\rhoTSDone(\sh_2) &= \sh_2^\star\\
\intertext{%
 and that 
}
\rhoTSDone\Bigl(\amgu\bigl(\sh_2, \{x \mapsto t\}\bigr)\Bigr) 
     &= \amgu\bigl(\sh_2, \{x \mapsto t\}\bigr)^\star.
\end{align*}
Thus, by the hypothesis,
\begin{align*}
  S &\in \bin\bigl(\rel(v_x, \sh_2^\star)^\star,
                  \rel(v_t, \sh_2^\star)^\star\bigr),\\
    &=  \bin\bigl(\rel(v_x, \sh_2^\star),
                  \rel(v_t, \sh_2^\star)\bigr).
\end{align*}
Therefore we can write 
\[
S= T_{\_} \union T_x \union R_{\_} \union R_t
\]
where 
\begin{align*}
T_{\_} \union T_x &\in \rel(v_x,\sh_2^\star),\\
R_{\_} \union R_t &\in \rel(v_t,\sh_2^\star),\\
T_{\_}, R_{\_} &\in \bigl(\sh_2 \setdiff \rel(v_{xt}, \sh_2)\bigr)^\star,\\
T_x &\in \rel(v_x,\sh_2)^\star\setdiff\emptyset,\\
R_t &\in \rel(v_t,\sh_2)^\star\setdiff\emptyset.
\end{align*}
Thus 
\begin{align*}
S &\in \Bigl(\bigl(\sh_2 \setdiff \rel(v_{xt}, \sh_2)\bigr) \union \bin\bigl(\rel(v_x, \sh_2)^\star,
                      \rel(v_t, \sh_2)^\star\bigr)\Bigr)^\star\\
   &= \amgu\bigl(\sh_2, \{x \mapsto t\}\bigr)^\star.
\end{align*}
\end{enumerate}

Combining case~1 and case~2b for $k=1$, 
the result follows immediately
by the monotonicity and extensivity of $(\cdot)^\star$.
\end{proof}

\begin{lem}
\label{lem:rho-equiv-implies-rho-rho-equiv}
For each $\sh_1, \sh_2 \in \SH$,
\[
  \rhoTSDk(\sh_1\union \sh_2)
    =
      \rhoTSDk\bigl(\rhoTSDk(\sh_1) \union \rhoTSDk(\sh_2)\bigr).
\]
\end{lem}
\begin{proof}
This is a classical property of upper closure operators \cite{GHK+80}.
\end{proof}

\begin{lem}
\label{lem:rho-equiv-implies-proj-cong}
For each $\sh_1, \sh_2 \in \SH$ and each $V \sseq \VI$,
\[
  \rhoTSDk(\sh_1) = \rhoTSDk(\sh_2)
   \implies
    \rhoTSDk\bigl(\proj(\sh_1, V)\bigr) = \rhoTSDk\bigl(\proj(\sh_2, V)\bigr).
\]
\end{lem}
\begin{proof}
We show that
\begin{align*}
  \sh_1 \sseq \rhoTSDk(\sh_2)
    \implies
      \proj(\sh_1, V)
        \sseq \rhoTSDk\bigl(\proj(\sh_2, V)\bigr).
\end{align*}
The result then follows from Eq.~(\ref{eq-emi-rho}).

Suppose $\sh_1 \sseq \rhoTSDk(\sh_2)$ and $S \in\proj(\sh_1, V)$.
Then, as $\proj$ is monotonic,
we have $S \in \proj\bigl(\rhoTSDk(\sh_2), V\bigr)$.
We distinguish two cases.
\begin{enumerate}
\item
There exists $x \in V$ such that $S = \{ x \}$.
Then $S \in \proj(\sh_2, V)$ and hence, by Definition~\ref{def:rhoSTk},
$S \in \rhoTSDk\bigl(\proj(\sh_2, V)\bigr)$.
\item
Otherwise, by definition of $\proj$ and Definition~\ref{def:rhoSTk},
there exists $S' \in \rhoTSDk(\sh_2)$ such that $S = S' \inters V$ and
\begin{align*}
  \forall T \sseq S'
    &\itc
      \Bigl(
        \card T < k
          \implies
            S = \bigunion \{\,
                            U \in \sh_2
                          \mid
                            T \sseq U \sseq S'
                          \,\}
                 \inters V
      \Bigr). \\
\intertext{%
Hence
}
  \forall T \sseq S
    &\itc
      \Bigl(
        \card T < k
          \implies
            S = \bigunion \bigl\{\,
                            U \in \proj(\sh_2, V)
                          \bigm|
                            T \sseq U \sseq S
                          \,\bigr\}
      \Bigr),
\end{align*}
and thus $S \in \rhoTSDk\bigl(\proj(\sh_2, V)\bigr)$.
\end{enumerate}
\end{proof}

\begin{proof}[Proof of Theorem~\ref{thm: no-loss-ops}.]
Statements 1, 2 and 3 follow from Lemmas
\ref{lem:rho-equiv-implies-amgu-cong},
\ref{lem:rho-equiv-implies-rho-rho-equiv} and
\ref{lem:rho-equiv-implies-proj-cong}, respectively.
\end{proof}

The following lemma is also proved
in~\cite{BagnaraHZ97b,BagnaraHZ01TCS}
but we include it here for completeness.
\begin{lem}
\label{lem:18}
Let $\sigma \defeq \{ x_1 \mapsto t_1, \ldots, x_n \mapsto t_n \}$,
where, for each $i = 1$, \dots,~$n$, $t_i$ is a ground term.
Then, for all $\sh \in \SH$ we have
\[
  \amgu(\sh, \sigma)
    = \sh \setdiff \rel\bigl(\{ x_1, \ldots, x_n \}, \sh\bigr).
\]
\end{lem}
\begin{proof*}
If $n = 0$, so that $\sigma = \emptyset$, the statement can be easily
verified after having observed that $\rel(\emptyset, \sh) = \emptyset$.
Otherwise, if $n > 0$, we proceed by induction on $n$.
For the base case, let $n = 1$.
Then
\begin{align*}
  \amgu(\sh, x_1 \mapsto t_1)
    &=
      \sh \setdiff \rel\bigl(\{x_1\}, \sh\bigr) \union
        \bin\Bigl(
              \rel\bigl(\{x_1\}, \sh\bigr)^\star,
              \rel\bigl(\emptyset, \sh\bigr)^\star
            \Bigr) \\
    &=
      \sh \setdiff \rel\bigl(\{x_1\}, \sh\bigr).
\end{align*}
For the inductive step, let $n > 1$ and let
\[
  \sigma' \defeq  \{ x_1 \mapsto t_1, \ldots, x_{n-1} \mapsto t_{n-1} \}.
\]
By definition of $\amgu$ we have
\begin{align*}
  \amgu(\sh, \sigma)
    &= \amgu\bigl(\sh, \{ x_n \mapsto t_n \} \union \sigma'\bigr) \\
    &= \amgu\Bigl(\amgu\bigl(\sh, \{ x_n \mapsto t_n \}\bigr), \sigma'\Bigr) \\
    &= \amgu\Bigl(\sh \setdiff \rel\bigl(\{x_n\}, \sh\bigr), \sigma'\Bigr) \\
    &= \Bigl(\sh \setdiff \rel\bigl(\{x_n\}, \sh\bigr)\Bigr)
         \setdiff
           \rel\Bigl(
                 \{ x_1, \ldots, x_{n-1} \},
                 \sh \setdiff \rel\bigl(\{x_n\}, \sh\bigr)
               \Bigr) \\
    &= \sh
         \setdiff
           \biggl(
             \rel\bigl(\{x_n\}, \sh\bigr)
               \union
                 \rel\Bigl(
                   \{ x_1, \ldots, x_{n-1} \},
                   \sh \setdiff \rel\bigl(\{x_n\}, \sh\bigr)
                 \Bigr)
           \biggl) \\
    &= \sh \setdiff \rel\bigl(\{ x_1, \ldots, x_n \}, \sh\bigr). \mathproofbox
\end{align*}
\end{proof*}

\begin{proof}[Proof of Theorem~\ref{thm: smallest-domain-for-ops}.]
We assume that $S \in \rhoTSDk(\sh_1) \setdiff \rhoTSDk(\sh_2)$.
(If such an $S$ does not exist we simply swap $\sh_1$ and $\sh_2$.)

Let $C$ denote a ground term and let
\[
\sigma \defeq \{\, x \mapsto C \mid x \in \VI \setdiff S \,\}.
\]
Then, by Lemma~\ref{lem:18}, for $i = 1$, $2$,
we define $\amgu(\sh_i,\sigma) \defeq \sh_i^S$
where
\begin{align*}
  \sh_1^S &\defeq \{\, T \sseq S \mid T \in \sh_1 \,\}, \\
  \sh_2^S &\defeq \{\, T \sslt S \mid T \in \sh_2 \,\}.
\end{align*}

Now, if $\card S = j$ and $j \leq k$,
then we have $S \in \sh_1 \setdiff \sh_2$.
Hence $S \in \sh_1^S \setdiff \sh_2^S$ and we can easily observe that
$S \in \rhoTSj(\sh_1^S)$ but $S \notin \rhoTSj(\sh_2^S)$.

On the other hand, if $\card S = j$ and $j > k$,
then by Definition~\ref{def:rhoSTk} there exists
$T$ with $\card T < k$ such that
\begin{align*}
  S &=     \bigunion \{\, U \in \sh_1^S \mid T \sseq U \,\} \\
\intertext{%
but
}
  S &\Ssgt \bigunion \{\, U \in \sh_2^S \mid T \sseq U \,\} \defeq S'.
\end{align*}
Let $x \in S \setdiff S'$.
We have $h \defeq \card \bigl(T \union \{x\}\bigr) \leq k$
and thus we can observe that
$T \union \{x\} \in \rhoTSh(\sh_1^S)$
but
$T \union \{x\} \notin \rhoTSh(\sh_2^S)$.
\end{proof}


\section{The Meet-Irreducible Elements}
\label{sec:meet-irreducible}

In Section~\ref{sec:decomposition},
we will use the method of Fil\'e and Ranzato~\cite{FileR96}
to decompose the dependency domains $\TSDk$.
In preparation for this, in this section, we identify the
meet-irreducible elements for the domains and state some general results.

We have already observed that $\TSk$ and $\TSDn = \SH$ are dual-atomistic.
However, $\TSDk$, for $k<n$, is not dual-atomistic and we need to
identify the meet-irreducible elements.
In fact, the set of dual-atoms for $\TSDk$ is
\[
  \dAtoms(\TSDk)
    =
      \bigl\{\,
        \SG \setdiff \{S\}
      \bigm|
        S \in \SG,
        \card S \leq k
      \,\bigr\}.
\]
Note that $\card\dAtoms(\TSDk) = \sum_{j=1}^k \binom{n}{j}$.
Specializing this for $k=1$ and $k=2$, respectively, we have
\begin{align*}
  \dAtoms(\Def)
    &=
      \bigl\{\,
        \SG \setdiff \{\{x\}\}
      \bigm|
        x \in \VI
      \,\bigr\}, \\
  \dAtoms(\PSD)
    &=
      \bigl\{\,
        \SG \setdiff \{S\}
      \bigm|
        S \in \pairs(\VI)
      \,\bigr\} \union \dAtoms(\Def),
\end{align*}
and we have $\card\dAtoms(\Def) = n$ and
$\card\dAtoms(\PSD) = n(n+1)/2$.
We present as an example of this the dual-atoms for $\Def$
and $\PSD$ when $n=3$.

\begin{exmp}
\label{ex: dual-atoms-def-sp}
Consider Example~\ref{ex: three-vars-datoms}.
Then the 3 dual-atoms for $\Def$ are $s_1$, $s_2$, $s_3$ and the 6
dual-atoms for $\PSD$ are  $s_1$, \dots,~$s_6$.
Note that these are not all the meet-irreducible elements since sets
that do not contain the sharing group $xyz$ such as $\{x\}$
and $\bot = \rhoDef(\bot) = \emptyset$ cannot be obtained by the
meet (which is set intersection) of a set of dual-atoms.
Thus, unlike $\Con$ and $\PS$, neither $\Def$ nor $\PSD$ are dual-atomistic.
\end{exmp}

Consider next the set $M_k$ of the meet-irreducible elements of $\TSDk$
that are neither the top element $\SG$ nor dual-atoms.
$M_k$ has an element for each sharing group $S \in \SG$
such that $\card S > k$
and each tuple  $T \sslt S$ with $\card T = k$.
Such an element is obtained from $\SG$
by removing all the sharing groups $U$ such that $T \sseq U \sseq S$.
Formally, for $1 \leq k \leq n$,
\[
  M_k
    \defeq
      \bigl\{\,
        \SG \setdiff \{\,
                       U \in \SG
                     \mid
                       T \sseq U \sseq S
                     \,\}
      \bigm|
        T,S \in \SG,
        T \sslt S,
        \card T =k
      \,\bigr\}.
\]
Note that, as there are $\binom{n}{k}$ possible choices for $T$
and $2^{n-k}-1$ possible choices for $S$, we have
$\card M_k = \binom{n}{k}(2^{n-k} -1)$ and
$\card \MI(\TSDk) = \sum_{j=0}^{k-1} \binom{n}{j} + \binom{n}{k} 2^{n-k}$.

We now show that we have identified precisely all the
meet-irreducible elements of $\TSDk$.
\begin{thm}
\label{thm: mi-elements}
If $k \in \Nset$ with $1 \leq k \leq n$,
then
\[
  \MI(\TSDk) = \{ \SG \} \union \dAtoms(\TSDk) \union M_k.
\]
\end{thm}
The proof of this theorem is included at the end of this section.
Here, we illustrate the result for the case when $n=3$.
\begin{exmp}
\label{ex:MI-Def-and-PSD}
Consider again Example~\ref{ex: dual-atoms-def-sp}.
First, consider the domain $\Def$.
The meet-irreducible elements which are not dual-atoms,
besides $\SG$, are the following (see Figure~\ref{fig:MI-Def}):
\begin{align*}
q_1 &= \{\phantom{x,{}} y,z,\phantom{xy,{}} xz,yz,xyz\} \sslt s_1, \\
q_2 &= \{\phantom{x,{}} y,z,xy,\phantom{xz,{}} yz,xyz\} \sslt s_1, &\qquad
  r_1 &= \{\phantom{x,{}} y,z,\phantom{xy,{}}\phantom{xz,{}}yz\}
    \sslt q_1 \inters q_2,\\
q_3 &= \{x,\phantom{y,{}} z,\phantom{xy,{}} xz,yz,xyz\} \sslt s_2, \\
q_4 &= \{x,\phantom{y,{}} z,xy,xz,\phantom{yz,{}} xyz\} \sslt s_2, &
  r_2 &= \{x,\phantom{y,{}} z,\phantom{xy,{}} xz \phantom{,yz}\}
    \sslt q_3 \inters q_4,\\
q_5 &= \{x,y,\phantom{z,{}} xy,\phantom{xz,{}} yz,xyz\} \sslt s_3, \\
q_6 &= \{x,y,\phantom{z,{}} xy,xz,\phantom{yz,{}} xyz\} \sslt s_3, &
  r_3 &= \{x,y,\phantom{z,{}} xy\phantom{{},xz} \phantom{{},yz}\}
    \sslt q_5 \inters q_6.
\end{align*}

Next, consider the domain $\PSD$.
The only meet-irreducible elements that are not dual-atoms,
beside $\SG$, are the following (see Figure~\ref{fig:MI-PSD}):
\begin{align*}
m_1 &= \{x,y,z, \phantom{xy,{}}  xz, yz\phantom{,xyz}\} \sslt s_4\\
m_2 &= \{x,y,z, xy, \phantom{xz,{}}  yz\phantom{,xyz}\} \sslt s_5\\
m_3 &= \{x,y,z, xy, xz  \phantom{,yz} \phantom{,xyz} \} \sslt s_6.
\end{align*}
Each of these lack a pair
and none contains the sharing group $xyz$.
\end{exmp}

\MakeShortTnput{\tnput}
\newcommand{\X}[3][0pt]{\Toval[framesep=-1mm,name=#3]{\scriptstyle\begin{matrix} #2 \end{matrix}}\tnput{\lower #1\hbox{$#3$}}}
\begin{figure}
\[
\pstree[treemode=R,treesep=0.44cm,levelsep=3cm]{\X{x,y,z \\ xy,xz,yz \\xyz}{SG}}{%
  \pstree{\X{\phantom{x,{}} y,z \\ xy,xz,yz \\ xyz}{s_1}}{%
    \pstree{\X[5pt]{\phantom{x,{}} y,z \\ \phantom{xy,{}} xz,yz \\ xyz}{q_1}}{%
      \X{\phantom{x,{}} y,z \\ \phantom{xy,{}} \phantom{xz,{}} yz
           \\ \phantom{xyz}}{r_1}
    }
    \X{\phantom{x,{}} y,z \\ xy,\phantom{xz,{}} yz \\ xyz}{q_2}
  }
  \pstree{\X{x,\phantom{y,{}} z \\ xy,xz,yz \\ xyz}{s_2}}{%
    \pstree{\X[5pt]{x,\phantom{y,{}} z \\ \phantom{xy,{}} xz,yz \\ xyz}{q_3}}{%
      \X{x,\phantom{y,{}} z \\ \phantom{xy,{}} xz \phantom{{},yz}
           \\ \phantom{xyz}}{r_2}
    }
    \X{x,\phantom{y,{}} z \\ xy,xz \phantom{{},yz} \\ xyz}{q_4}
  }
  \pstree{\X{x,y\phantom{{},z} \\ xy,xz,yz \\ xyz}{s_3}}{%
    \pstree{\X[5pt]{x,y\phantom{{},z} \\ xy,\phantom{xz,{}} yz \\ xyz}{q_5}}{%
      \X{x,y\phantom{{},z} \\ xy\phantom{{},xz,yz}
           \\ \phantom{xyz}}{r_3}
    }
    \X{x,y\phantom{{},z} \\ xy,xz\phantom{{},yz} \\ xyz}{q_6}
  }
}
\ncline{q_2}{r_1}
\ncline{q_4}{r_2}
\ncline{q_6}{r_3}
\ncbox[linearc=.3,boxsize=1.5,linestyle=dashed,nodesep=.4]{s_1}{s_3}
\]
\caption{The meet-irreducible elements of $\Def$
         for $n = 3$, with dual-atoms emphasized.}
\label{fig:MI-Def}
\end{figure}

\begin{figure}
\[
\pstree[treemode=R,treesep=0.44cm,levelsep=3cm]{\X{x,y,z \\ xy,xz,yz \\xyz}{SG}}{%
  \X{\phantom{x,{}} y,z \\ xy,xz,yz \\ xyz}{s_1}
  \X{x,\phantom{y,{}} z \\ xy,xz,yz \\ xyz}{s_2}
  \X{x,y\phantom{{},z} \\ xy,xz,yz \\ xyz}{s_3}
  \pstree{\X[5pt]{x,y,z \\ \phantom{xy,{}} xz,yz \\ xyz}{s_4}}{%
    \X{x,y,z \\ \phantom{xy,{}} xz,yz \\ \phantom{xyz}}{m_1}
  }
  \pstree{\X[5pt]{x,y,z \\ xy,\phantom{xz,{}} yz \\ xyz}{s_5}}{%
    \X{x,y,z \\ xy,\phantom{xz,{}} yz \\ \phantom{xyz}}{m_2}
  }
  \pstree{\X[5pt]{x,y,z \\ xy,xz\phantom{{},yz} \\ xyz}{s_6}}{%
    \X{x,y,z \\ xy,xz \phantom{{},yz} \\ \phantom{xyz}}{m_3}
  }
}
\ncbox[linearc=.3,boxsize=1.5,linestyle=dashed,nodesep=.4]{s_1}{s_6}
\]
\caption{The meet-irreducible elements of $\PSD$
         for $n = 3$, with dual-atoms emphasized.}
\label{fig:MI-PSD}
\end{figure}

Looking at Examples~\ref{ex: Con-PS-datoms}
and~\ref{ex:MI-Def-and-PSD}, it can be seen that
all the dual-atoms of the domains $\Con$ and $\PS$
are meet-irreducible elements
of the domains $\Def$ and $\PSD$, respectively.
Indeed, the following general result shows that
the dual-atoms of the domain $\TSk$
are meet-irreducible elements for the domain $\TSDk$.
\begin{cor}
\label{cor:mi-TSDk-and-dAtoms-TSk}
Let $k \in \Nset$ with $1 \leq k \leq n$.
Then
\[
  \dAtoms(\TSk) = \bigl\{\, \sh \in \MI(\TSDk) \bigm| \VI \notin \sh \,\bigr\}.
\]
\end{cor}

For the decomposition, we need to identify which
meet-irreducible elements of $\TSDk$ are in $\TSj$.
Using Corollaries~\ref{cor:TSDk-vs-TSj}
and~\ref{cor:mi-TSDk-and-dAtoms-TSk}
we have the following result.
\begin{cor}
\label{cor:MI-TSDk-inters-TSj}
If $j, k \in \Nset$ with $1 \leq j < k \leq n$,
then
\(
  \MI(\TSDk) \inters \TSj = \{ \SG \}.
\)
\end{cor}
By combining Proposition~\ref{prop:TSDk-chain}
with Theorem~\ref{thm: mi-elements}
we can identify the meet-irreducible elements of $\TSDk$ that are in
$\TSDj$, where $j < k$. 
\begin{cor}
\label{cor:MI-TSDk-inters-TSDj}
If
$j, k \in \Nset$ with
$1 \leq j < k \leq n$,
then \[\MI(\TSDk) \inters \TSDj = \dAtoms(\TSDj).\]
\end{cor}

\subsection{Proof of Theorem~\ref{thm: mi-elements}}

\begin{proof}[Proof of Theorem~\ref{thm: mi-elements}.]
We prove the two inclusions separately.
\begin{enumerate}
\item[1.]
$\MI(\TSDk) \Sseq \{\SG\} \union \dAtoms(\TSDk) \union M_k$.

Let $m$ be in the right-hand side. If $m \in \{\SG\} \union \dAtoms(\TSDk)$
there is nothing to prove.
Therefore we assume $m \in M_k$.
We need to prove that if $\sh_1, \sh_2 \in \TSDk$ and
\[
  m = \sh_1 \meet \sh_2 \defeq \sh_1 \inters \sh_2
\]
then $m = \sh_1$ or $m = \sh_2$.
Obviously, we have $m \sseq \sh_1$ and $m \sseq \sh_2$.
Moreover, by definition of $M_k$,
there exist $T, S \in \SG$ where $\card T=k$ and $T \sslt S$ such that
\[
  m = \SG \setdiff \bigl\{\, U \in \SG \bigm| T \sseq U \sseq S \,\bigr\}.
\]
Since $S \notin m$, we have $S \notin \sh_1$ or $S \notin \sh_2$.
Let us consider the first case (the other is symmetric).
Then, applying the definition of $\TSDk$,
there is a $T' \sslt S$ with $\card T' < k$ such that
\[
  \bigunion \{\, U'\in \sh_1 \mid T' \sseq U' \sseq S \,\} \neq S.
\]
Since $\card T' < \card T$, there exists $x$ such that
$x \in T \setdiff T'$. Thus $T' \sslt S\setdiff\{x\}$ and
$S \setdiff \{x\}\in m$. Hence, as $m \sseq \sh_1$,
we have $S \setdiff \{x\}\in \sh_1$.
Consider an arbitrary $U \in \SG$ where $T\sseq U \sseq S$. 
Then $x\in U$. Thus,
since $S = \bigl(S\setdiff\{x\}\bigr) \union U$ and $S\notin \sh_1$,
 $U\notin \sh_1$. 
Thus, as this is true for all such $U$, $\sh_1 \sseq m$.

\item[2.]
$\MI(\TSDk) \sseq \{\SG\} \union \dAtoms(\TSDk) \union M_k$.

Let $\sh \in \TSDk$.
We need to show that $\sh$ is the meet of elements in the right-hand side.
If $\sh = \SG$ then there is nothing to prove.
Suppose $\sh \neq \SG$.
For each $S \in \SG$ such that
$S \notin \sh$, we will show there is an element $m_S$ in the right-hand side
such that $S \notin m_S$ and $\sh \sseq m_S$.
Then $\sh = \biginters \{\, m_S \mid S \notin \sh \,\}$.

There are two cases.
\begin{enumerate}
\item[2a.]
$\card S \leq k$;
Let $m_S = \SG \setdiff \{S\}$.
Then $m_S \in \dAtoms(\TSDk)$ and $\sh \sseq m_S$.

\item[2b.]
$\card S > k$;
in this case, applying the definition of $\TSDk$,
there must exist a set $T' \sslt S$ with $\card T' < k$
such that
\[
   \bigunion \{\, U'\in \sh \mid T' \sslt U' \sseq S \,\} \sslt S.
\]
However, since $T' \sslt S$, we have
$S =
  \bigunion \bigl\{\, T'\union\{x\} \bigm| x \in S\setdiff T' \,\bigr\}$.
Thus, for some $x\in S\setdiff T'$, if
$U$ is such that $T'\union\{x\} \sseq U \sseq S$ then $U \notin \sh$.
Choose $T \in \SG$ so that $T'\union\{x\} \sseq T$ and $\card T = k$ and
let $m_S = \SG\setdiff \{\, U \in \SG \mid T \sseq U \sseq S \,\}$.
Then $m_S \in M_k$, $S\notin m_S$, and $\sh\sseq m_S $.
\end{enumerate}
\end{enumerate}
\end{proof}


\section{The Decomposition of the Domains}
\label{sec:decomposition}

\subsection{Removing the Tuple-Sharing Domains}

We first consider the decomposition of $\TSDk$ with respect to $\TSj$.
It follows from Theorem~\ref{thm:FileR96}
and Corollaries~\ref{cor:TSDk-vs-TSj} and \ref{cor:MI-TSDk-inters-TSj}
that, for $1\leq j < k \leq n$, we have
\begin{align}
   \TSDk \sim \TSj
                 &= \Moore\bigl( \MI(\TSDk)\setdiff\rhoTSj(\TSDk)\bigr)\notag\\
                 &= \Moore\bigl( \MI(\TSDk)\setdiff\TSj\bigr)\notag\\
                 &= \TSDk.
                      \label{eq: TSDk-TSj}
\end{align}
Since $\SH = \TSDn$, we have,
using Eq.~(\ref{eq: TSDk-TSj}) and setting $k=n$,
that, if $j<n$,
\begin{equation}
 \SH \sim \TSj = \SH.
\label{eq: sh-TSj}
\end{equation}
Thus, in general,
$\TSj$ is too abstract to be removed from $\SH$ by means of
complementation.
(Note that here it is required $j < n$, because we have
$\SH \sim \TSn \neq \SH$.)
In particular, letting $j=1$, $2$ (assuming $n>2$) in Eq.~(\ref{eq: sh-TSj}),
we have
\begin{equation}
  \SH \sim \PS = \SH \sim \Con = \SH,
  \label{eq: sh-con}
\end{equation}
showing that $\Con$
and $\PS$ are too abstract to be
removed from $\SH$ by means of complementation.
Also, by Eq.~(\ref{eq: TSDk-TSj}), letting $j=1$ and $k=2$ it follows
that the complement of $\Con$ in $\PSD$ is $\PSD$.

Now consider decomposing $\TSDk$ using $\TSk$.
It follows from Theorem~\ref{thm:FileR96}, Proposition \ref{prop:TSDk-vs-TSk}
and Corollary~\ref{cor:mi-TSDk-and-dAtoms-TSk}
that, for $1 \leq k \leq n$,  we have
\begin{align}
   \TSDk \sim \TSk
                 &= \Moore\bigl( \MI(\TSDk)\setdiff\rhoTSk(\TSDk)\bigr)\notag\\
                 &= \Moore\bigl( \MI(\TSDk)\setdiff\TSk\bigr)\notag\\
                 &= \{\, \sh\in\TSDk \, \mid \VI \, \in \sh \,\}.
                      \label{eq: TSDk-TSk}
\end{align}
Thus we have
\begin{equation}
         \TSDk \sim (\TSDk \sim \TSk) = \TSk.
            \label{eq: TSDk-TSDk}
\end{equation}
We have therefore extracted \emph{all} the domain $\TSk$
from $\TSDk$.
So by letting $k=1$, $2$ in Eq.~(\ref{eq: TSDk-TSk}),
we have found the complements of $\Con$ in
$\Def$ and $\PS$ in $\PSD$:
\begin{align*}
  \Def \sim \Con &= \{\,\sh \in \Def \mid \VI \in \sh \,\}, \\
  \PSD \sim \PS &= \{\,\sh \in \PSD \mid \VI \in \sh \,\}.
\end{align*}
Thus if we denote the domains induced by these complements as
$\Defoplus$ and $\PSDoplus$, respectively, we have the following result.
\begin{thm}
\begin{alignat*}{2}
         \Def \sim \Con &= \Defoplus,
         &\qquad\Def \sim \Defoplus &= \Con,\\
          \PSD \sim \PS &= \PSDoplus,
         &\qquad\PSD \sim \PSDoplus &= \PS.
\end{alignat*}
Moreover, $\Con$ and $\Defoplus$ form a minimal decomposition
for $\Def$ and, similarly, $\PS$ and $\PSDoplus$ form a minimal decomposition
for $\PSD$.
\end{thm}

\subsection{Removing the Dependency Domains}

First we note that, by Theorem \ref{thm: mi-elements},
Proposition~\ref{prop:TSDk-chain}, and Corollary~\ref{cor:MI-TSDk-inters-TSDj},
the complement of
$\TSDj$ in $\TSDk$, where $1 \leq j < k \leq n$, is given as follows:
\begin{align}
\TSDk \sim \TSDj
          &= \Moore\bigl(\MI(\TSDk)\setdiff \rhoTSDj(\TSDk)\bigr)\notag\\
          &= \Moore\bigl(\MI(\TSDk)\setdiff \TSDj\bigr)\notag\\
          &= \bigl\{\,
               \sh\in\TSDk
             \bigm|
                \forall S\in \SG \itc \card S \leq j \implies S\in \sh
             \,\bigr\}.
           \label{eq: TSDk-TSDj}
 \end{align}
It therefore follows from Eq.~(\ref{eq: TSDk-TSDj}) and setting $k=n$
that the complement of $\rhoTSDj$ in $\SH$
for $j<n$ is:
\begin{align}
    \SH \sim \TSDj
          &= \bigl\{\,
               \sh\in\SH
             \bigm|
                \forall S\in \SG \itc \card S \leq j \implies S\in \sh
             \,\bigr\}
          \label{eq: SH-TSDj}\\
          &\defeq \SHjplus.\notag
           \end{align}
In particular, in Eq. (\ref{eq: SH-TSDj}) when $j = 1$,
we have the following result for $\Def$,
also proved in~\cite[Lemma 5.4]{FileR96}:
\begin{align*}
  \SH \sim \Def
    &=
      \bigl\{\,
        \sh\in\SH
      \bigm|
        \forall x\in \VI \itc \{x\}\in \sh
      \,\bigr\}\\
    &\defeq
      \SHDefplus.
\intertext{%
Also, in Eq. (\ref{eq: SH-TSDj}) when $j = 2$, 
we have the following result for $\PSD$:
}
    \SH \sim \PSD
          &= \bigl\{\,
              \sh \in \SH
            \bigm|
              \forall S\in \SG \itc \card S \leq 2 \implies S\in \sh
            \,\bigr\}\\
    &\defeq
      \SHPSDplus.
\end{align*}

We next construct the complement of $\PSD$ with respect
to $\Def$.
By Eq.~(\ref{eq: TSDk-TSDj}),
\begin{equation*}
\begin{split}
  \PSD \sim \Def
    &=
       \bigl\{\,
         \sh\in \PSD
       \bigm|
         \forall x\in \VI \itc \{x\}\in \sh
       \,\bigr\} \\
    &\defeq \PSDplus.
\end{split}
\end{equation*}
Then the complement factor
$\Defminus \defeq \PSD \sim \PSDplus$
is exactly the same thing as
$\SH \sim \SHDefplus$
so that $\PSD$ and $\SH$ behave similarly for $\Def$.

\subsection{Completing the Decomposition}

Just as for $\SH$, the complement of $\SHDefplus$ using $\PS$
(or, more generally, $\TSj$ where $1 < j < n$) is $\SHDefplus$.
By Corollary~\ref{cor:mi-TSDk-and-dAtoms-TSk}
and Theorem~\ref{thm:FileR96},
as $\PS$ is dual-atomistic,
the complement of $\PS$ in $\PSD^+$ is given as follows.
\begin{thm}
\begin{align*}
  \PSDplusplus
    &\defeq
      \PSDplus \sim \PS \\
    &=
      \bigl\{\,
        \sh \in \PSD
      \bigm|
        \VI \in \sh, \forall x \in \VI: \{x\} \in \sh
      \,\bigr\}, \\
  \PSDplus \sim \PSDplusplus
    &=
      \PS.
\end{align*}
\end{thm}
So, we have extracted \emph{all} the domain $\PS$
from $\PSDplus$ and we have the following result
(see Figure~\ref{fig:PSD-decomposition}).
\begin{cor}
    $\Defminus$, $\PS$, and $\PSDplusplus$ form a minimal decomposition
    for $\PSD$.
\end{cor}

\begin{figure}[t!]
\def\objectstyle{\displaystyle}
\xymatrix@!C=1cm@!R=1cm{
  \Defminus & & \TStwo = \PS & & \PSDplusplus \\
  & & & \PSDplus \ar@{-}[ul] \ar@{-}[ur] \\
  & & \TSDtwo = \PSD \ar@{-}[ulul] \ar@{-}[ur] \\
}
\caption{A non-trivial decomposition of $\PSD$.}
\label{fig:PSD-decomposition}
\end{figure}

\section{Discussion}
\label{sec:discussion}

By studying the sharing domain $\SH$ in a more general framework,
we have been able to show that the domain $\PSD$ has a natural place
in a scheme of domains based on $\SH$.
Since the well-known domain $\Def$ for groundness analysis
is an instance of this scheme,
we have been able to highlight the close relationship
between $\Def$ and $\PSD$
and the many properties they share. In particular,
it was somehow unexpected that these domains could both be
obtained as instances of a single parametric construction.
As another contribution, we have generalized and strengthened the results
in~\cite{CortesiFW94,CortesiFW98} and~\cite{BagnaraHZ97b,BagnaraHZ01TCS}
stating that
\begin{itemize}
\item
$\Def$ is the quotient of $\SH$ with respect to
the groundness domain $G \equiv \Con$; and
\item
$\PSD$ is the quotient of $\SH$ with respect to
the reduced product $\Con \ucomeet \PS$ of groundness and pair-sharing.
\end{itemize}

In the view of recent results
on abstract domain completeness~\cite{GiacobazziR97},
these points can be restated by saying that $\Def$ and $\PSD$ are
the \emph{least fully-complete extensions} (lfce's) of $\Con$ and
$\Con \ucomeet \PS$ with respect to $\SH$, respectively.

From a theoretical point of view,
the quotient of an abstract domain 
with respect to a property of interest
and
the least fully-complete extension of this same property
with respect to the given abstract domain
are not equivalent.
While the lfce is defined for any semantics given by means of continuous
operators over complete lattices,
it is known \cite{CortesiFW94,CortesiFW98} that the quotient may not exist.
However, it is also known \cite{GiacobazziSR98b} that
when the quotient exists it is exactly the same as the lfce,
so that the latter has also been called \emph{generalized quotient}.
In particular, for all the domains considered in this paper,
these two approaches to the completeness problem in abstract interpretation
are equivalent.

In~\cite{BagnaraHZ97b,BagnaraHZ01TCS},
we wrote that $\PSD \sim \PS \neq \PSD$.
This paper now clarifies that statement.
We have provided a minimal decomposition for $\PSD$ whose components
include $\Defminus$ and $\PS$.
Moreover, we have shown that $\Def$ and $\PSD$ are \emph{not} dual-atomistic
and we have completely specified their meet-irreducible elements.
Our starting point was the work of Fil\'e and Ranzato.
In \cite{FileR96}, they noted, as we have,
that $\SHDefplus \sim \PS = \SHDefplus$
so that nothing of the domain $\PS$
could be extracted from $\SHDefplus$.
They observed that $\rhoPS$ maps all dual-atoms that contain
the sharing group $\VI$ to the top element $\SG$ and
thus lose all pair-sharing information.
To avoid this, they replaced the classical pair-sharing domain $\PS$
with the domain $\PS'$ where,
for all $\sh \in \SHDefplus$,
\[
  \rhoPSprime(\sh) = \rhoPS(\sh) \setdiff \bigl(\{\VI\} \setdiff \sh\bigr),
\]
and noted that
$\SHDefplus \sim \PS' = \{\, \sh\in \SHDefplus \mid \VI \in \sh \,\}$.
To understand the nature of this new domain $\PS'$, we first observe that,
\[
  \PS' = \PS \ucomeet \TSn.
\]
This is because
$\TSn = \MI(\TSn) = \bigl\{ \SG \setdiff\{\VI\}, \SG \bigr\}$.
In addition,
\[
  \SHDefplus \sim \TSn = \{\, \sh\in \SHDefplus \mid \VI \in \sh \,\},
\]
which is precisely the same as $\SHDefplus \sim \PS'$.
Thus, since $\SHDefplus \sim \PS = \SHDefplus$,
it is not surprising that it is precisely the \emph{added}
component $\TSn$ that is removed when we compute the complement for
$\SHDefplus$ with respect to $\PS'$.

We would like to point out that, in our opinion,
the problems outlined above
are not the consequence of the particular domains considered.
Rather, they are mainly related to the methodology for decomposing a domain.
As shown here, complementation \emph{alone} is
not sufficient to obtain \emph{truly minimal} decompositions of domains.
The reason being that complementation only depends on the domain's data
(that is, the domain elements and the partial order relation modeling
their intrinsic precision), while it is completely independent from
the domain operators that manipulate that data.
In particular, if the concrete domain contains elements that are redundant
with respect to its operators (because the observable behavior of these
elements
is exactly the same in all possible program contexts) then any factorization
of the domain obtained by complementation will encode this redundancy.
However, the theoretical solution to this problem is well-known
\cite{CortesiFW94,CortesiFW98,GiacobazziR97,GiacobazziSR98b}
and it is straightforward to improve the methodology so as to obtain
truly minimal decompositions: \emph{first} remove all redundancies
from the domain (this can be done by computing the quotient of the domain
with respect to the observable behavior)
and only \emph{then} decompose it by complementation.
This is precisely what is done here.

We conclude our discussion about complementation with a few remarks.
It is our opinion that, from a theoretical point of view,
complementation is an excellent concept to work with:
by allowing the splitting of complex domains into simpler components,
avoiding redundancies between them,
it really enhances our understanding of the domains themselves.

However, as things stand at present, complementation has never been
exploited from a practical point of view.
This may be because it is easier to implement a single complex domain
than to implement several simpler domains and integrate them together.
Note that complementation requires the implementation of a
full integration between components
(i.e., the reduced product together with its corresponding
best approximations of the concrete semantic operators),
otherwise precision would be lost and
the theoretical results would not apply.

Moreover, complementation appears to have little relevance
when trying to design or evaluate better implementations
of a known abstract domain.
In particular, this reasoning applies to the use of complementation
as a tool for obtaining space saving representations for domains.
As a notable example, the GER representation for $\Pos$ \cite{BagnaraS99}
is a well-known domain decomposition that does enable
significant memory and time savings with no precision loss.
This is not (and could not be) based on complementation.
Observe that the complement of $G$
with respect to $\Pos$ is $\Pos$ itself.
This is because of the isomorphisms
$\Pos \equiv \SH$ \cite{CodishS98} and $G \equiv \Con \defeq \TSone$
so that, by Eq.~(\ref{eq: sh-con}), $\Pos \sim G = \Pos$.
It is not difficult to observe that the same phenomenon happens if one
considers the groundness equivalence component $E$, that is,
$\Pos \sim E = \Pos$.
Intuitively, each element of the domain $E$ defines a partition
of the variable of interest $\VI$ into groundness equivalence classes.
In fact, it can be shown that two variables $x,y \in \VI$
are ground-equivalent in the abstract element $\sh \in \SH \equiv \Pos$
if and only if $\rel\bigl(\{x\}, \sh\bigr) = \rel\bigl(\{y\}, \sh\bigr)$.
In particular, this implies both $\{x\} \notin \sh$ and $\{y\} \notin \sh$.
Thus, it can be easily observed that in all the dual-atoms of $\Pos$
no variable is ground-equivalent to another variable
(because each dual-atom lacks just a \emph{single} sharing group).

A new domain for pair-sharing analysis 
has been defined in~\cite{Scozzari00} as
\[
  \ScozzariShPSh = \PSDplus \ucomeet A,
\]
where the $A$ component is a strict abstraction
of the well-known groundness domain $\Pos$.
It can be seen from the definition that
$\ScozzariShPSh$ is a close relative of $\PSD$.
This new domain is obtained, just as in the case for $\PSD$,
by a construction
that starts from the set-sharing domain $\SH \equiv \mathsf{Sh}$
and aims at deriving the pair-sharing information
encoded by $\PS \equiv \mathsf{PSh}$.
However, instead of applying the generalized quotient operator
used to define $\PSD$,
the domain $\ScozzariShPSh$ is obtained by applying
a new domain-theoretic operator
that is based on the concept of \emph{optimal semantics}
\cite{GiacobazziSR98a}.

When comparing $\ScozzariShPSh$ and $\PSD$,
the key point to note is that $\ScozzariShPSh$ is neither
an abstraction nor a concretization of the starting domain $\SH$.
On the one hand $\ScozzariShPSh$
is strictly more precise for computing pair-sharing,
since it contains formulas of $\Pos$ that are not in the domain $\SH$.
On the other hand $\SH$ and $\PSD$ are strictly more precise
for computing groundness, since $\ScozzariShPSh$ does not
contain all of $\Def$: in particular, 
it does not contain any of the elements in $\Con$.

While these differences are correctly stated in~\cite{Scozzari00},
the informal discussion goes further.
For instance, it is argued in~\cite[Section 6.1]{Scozzari00} that
\begin{quotation}
``in [\cite{BagnaraHZ01TCS}] the domain $\PSD$ is compared
to its proper abstractions only,
which is a rather restrictive hypothesis\ldots''
\end{quotation}
This hypothesis is not one that was made in \cite{BagnaraHZ01TCS}
but is a distinctive feature of the generalized quotient approach itself.
Moreover, such an observation is not really appropriate
because, when devising the $\PSD$ domain,
the goal was to \emph{simplify} the starting domain $\SH$
without losing precision on the observable $\PS$.
This is the objective of the generalized quotient operator
and, in such a context, the ``rather restrictive hypothesis''
is not restrictive at all.

The choice of the generalized quotient can also provide several
advantages that have been fully exploited in~\cite{BagnaraHZ01TCS}.
Since an implementation for $\SH$ was available,
the application of this operator resulted in
an \emph{executable} specification of the simpler domain $\PSD$.
By just optimizing this executable specification it was possible
to arrive at a much more efficient implementation:
exponential time and space savings have been achieved
by removing the redundant sharing groups from the computed elements and
by replacing the star-union operator with the 2-self-union operator.
Moreover, the executable specification inherited
all the correctness results readily available for that
implementation of $\SH$, so that the only new result
that had to be proved was the correctness of the optimizations.

These advantages do not hold for the domain $\ScozzariShPSh$.
In fact, the definition of a feasible representation
for its elements and, a fortiori, the definition of
an executable specification of the corresponding abstract operators
seem to be open issues.\footnote{In \cite{Scozzari00},
the only representation given for the elements of $\ScozzariShPSh$
is constituted by infinite sets of substitutions.}
Most importantly, the required correctness results
cannot be inherited from those of $\SH$.
All the above reasons indicate that the generalized quotient
was a sensible choice when looking for a domain simpler than $\SH$
while preserving precision on $\PS$.

Things are different if the goal is
\emph{to improve the precision of a given analysis}
with respect to the observable,
as was the case in~\cite{Scozzari00}.
In this context the generalized quotient would be
the wrong choice, since by definition it cannot help,
whereas the operator defined in~\cite{Scozzari00} could be useful.


\section{Conclusion}
\label{sec:conclusion}

We have addressed the problem of deriving a non-trivial decomposition
for abstract domains tracking groundness and sharing information
for logic languages by means of complementation.
To this end, we have defined a general schema of domains approximating
the set-sharing domain of Jacobs and Langen and we have generalized and
strengthened known completeness and minimality results.
From a methodological point of view, our investigation has shown that,
in order to obtain truly minimal decompositions of abstract interpretation
domains, complementation should be applied to a reference domain already
enjoying a minimality result with respect to the observable property.

\section*{Acknowledgment}

We recognize the hard work required to review technical papers
such as this one and would like to express our real gratitude
to the Journal referees for their critical reading and constructive
suggestions for preparing this improved version.

%\bibliographystyle{dcu}
%\bibliography{mybib}

\hyphenation{ Bruy-noo-ghe Fa-la-schi Her-men-e-gil-do Lu-ba-chev-sky
  Pu-ru-sho-tha-man Roe-ver Ros-en-krantz Ru-dolph }
\begin{thebibliography}{xx}

\harvarditem[Armstrong et al.]{Armstrong, Marriott, Schachte and
  S{\o}ndergaard}{1998}{ArmstrongMSS98}
Armstrong, T., Marriott, K., Schachte, P. and S{\o}ndergaard, H.  (1998).
\newblock Two classes of {Boolean} functions for dependency analysis, {\em
  Science of Computer Programming} {\bf 31}(1):~3--45.

\harvarditem[Bagnara and Schachte]{Bagnara and Schachte}{1999}{BagnaraS99}
Bagnara, R. and Schachte, P.  (1999).
\newblock Factorizing equivalent variable pairs in {ROBDD}-based
  implementations of \textit{Pos}, {\em in} A.~M. Haeberer (ed.), {\em
  Proceedings of the ``Seventh International Conference on Algebraic
  Methodology and Software Technology (AMAST'98)''}, Vol. 1548 of {\em Lecture
  Notes in Computer Science}, Springer-Verlag, Berlin, Amazonia, Brazil,
  pp.~471--485.

\harvarditem[Bagnara et al.]{Bagnara, Hill and Zaffanella}{1997}{BagnaraHZ97b}
Bagnara, R., Hill, P.~M. and Zaffanella, E.  (1997).
\newblock Set-sharing is redundant for pair-sharing, {\em in} P.~{Van
  Hentenryck} (ed.), {\em Static Analysis: Proceedings of the 4th International
  Symposium}, Vol. 1302 of {\em Lecture Notes in Computer Science},
  Springer-Verlag, Berlin, Paris, France, pp.~53--67.

\harvarditem[Bagnara et al.]{Bagnara, Hill and
  Zaffanella}{2001}{BagnaraHZ01TCS}
Bagnara, R., Hill, P.~M. and Zaffanella, E.  (2001).
\newblock Set-sharing is redundant for pair-sharing, {\em Theoretical Computer
  Science}.
\newblock To appear.

\harvarditem[Codish and S{\o}ndergaard]{Codish and
  S{\o}ndergaard}{1998}{CodishS98}
Codish, M. and S{\o}ndergaard, H.  (1998).
\newblock The {Boolean} logic of set sharing analysis, {\em in} C.~Palamidessi,
  H.~Glaser and K.~Meinke (eds), {\em Principles of Declarative Programming},
  Vol. 1490 of {\em Lecture Notes in Computer Science}, Springer-Verlag,
  Berlin, Pisa, Italy, pp.~89--100.

\harvarditem[Colmerauer]{Colmerauer}{1982}{Colmerauer82}
Colmerauer, A.  (1982).
\newblock {Prolog} and infinite trees, {\em in} K.~L. Clark and S.~{\AA}.
  T{\"a}rnlund (eds), {\em Logic Programming, APIC Studies in Data Processing},
  Vol.~16, Academic {P}ress, New York, pp.~231--251.

\harvarditem[Colmerauer]{Colmerauer}{1984}{Colmerauer84}
Colmerauer, A.  (1984).
\newblock Equations and inequations on finite and infinite trees, {\em
  Proceedings of the International Conference on Fifth Generation Computer
  Systems (FGCS'84)}, ICOT, Tokyo, Japan, pp.~85--99.

\harvarditem[Cortesi and Fil\'e]{Cortesi and Fil\'e}{1999}{CortesiF99}
Cortesi, A. and Fil\'e, G.  (1999).
\newblock Sharing is optimal, {\em Journal of Logic Programming} {\bf
  38}(3):~371--386.

\harvarditem[Cortesi et al.]{Cortesi, Fil\'e and
  Winsborough}{1994}{CortesiFW94}
Cortesi, A., Fil\'e, G. and Winsborough, W.  (1994).
\newblock The quotient of an abstract interpretation for comparing static
  analyses, {\em in} M.~Alpuente, R.~Barbuti and I.~Ramos (eds), {\em
  Proceedings of the ``1994 Joint Conference on Declarative Programming
  (GULP-PRODE'94)''}, Pe\~n\'{\i}scola, Spain, pp.~372--397.
\newblock An extended version has been published as \cite{CortesiFW98}.

\harvarditem[Cortesi et al.]{Cortesi, Fil\'e and
  Winsborough}{1996}{CortesiFW96}
Cortesi, A., Fil\'e, G. and Winsborough, W.  (1996).
\newblock Optimal groundness analysis using propositional logic, {\em Journal
  of Logic Programming} {\bf 27}(2):~137--167.

\harvarditem[Cortesi et al.]{Cortesi, Fil\'e and
  Winsborough}{1998}{CortesiFW98}
Cortesi, A., Fil\'e, G. and Winsborough, W.  (1998).
\newblock The quotient of an abstract interpretation for comparing static
  analyses, {\em Theoretical Computer Science} {\bf 202}(1{\&}2):~163--192.

\harvarditem[Cortesi et al.]{Cortesi, Fil\'e, Giacobazzi, Palamidessi and
  Ranzato}{1995}{CortesiFGPR95}
Cortesi, A., Fil\'e, G., Giacobazzi, R., Palamidessi, C. and Ranzato, F.
  (1995).
\newblock Complementation in abstract interpretation, {\em in} A.~Mycroft
  (ed.), {\em Static Analysis: Proceedings of the 2nd International Symposium},
  Vol. 983 of {\em Lecture Notes in Computer Science}, Springer-Verlag, Berlin,
  Glasgow, UK, pp.~100--117.

\harvarditem[Cortesi et al.]{Cortesi, Fil\'e, Giacobazzi, Palamidessi and
  Ranzato}{1997}{CortesiFGPR97}
Cortesi, A., Fil\'e, G., Giacobazzi, R., Palamidessi, C. and Ranzato, F.
  (1997).
\newblock Complementation in abstract interpretation, {\em ACM Transactions on
  Programming Languages and Systems} {\bf 19}(1):~7--47.

\harvarditem[Cousot and Cousot]{Cousot and Cousot}{1979}{CousotC79}
Cousot, P. and Cousot, R.  (1979).
\newblock Systematic design of program analysis frameworks, {\em Proceedings of
  the Sixth Annual ACM Symposium on Principles of Programming Languages},
  pp.~269--282.

\harvarditem[Fil\'e and Ranzato]{Fil\'e and Ranzato}{1996}{FileR96}
Fil\'e, G. and Ranzato, F.  (1996).
\newblock Complementation of abstract domains made easy, {\em in} M.~Maher
  (ed.), {\em Logic Programming: Proceedings of the Joint International
  Conference and Symposium on Logic Programming}, MIT Press Series in Logic
  Programming, The MIT Press, Bonn, Germany, pp.~348--362.

\harvarditem[Giacobazzi and Ranzato]{Giacobazzi and
  Ranzato}{1997}{GiacobazziR97}
Giacobazzi, R. and Ranzato, F.  (1997).
\newblock Completeness in abstract interpretation: a domain perspective, {\em
  in} M.~Johnson (ed.), {\em Proceedings of the 6th International Conference on
  Algebraic Methodology and Software Technology (AMAST'97)}, Vol. 1349 of {\em
  Lecture Notes in Computer Science}, Springer-Verlag, Berlin, Sydney,
  Australia, pp.~231--245.

\harvarditem[Giacobazzi et al.]{Giacobazzi, Ranzato and
  Scozzari}{1998a}{GiacobazziSR98a}
Giacobazzi, R., Ranzato, F. and Scozzari, F.  (1998a).
\newblock Building complete abstract interpretations in a linear logic-based
  setting,  {\em in} \citeasnoun{SAS98}, pp.~215--229.

\harvarditem[Giacobazzi et al.]{Giacobazzi, Ranzato and
  Scozzari}{1998b}{GiacobazziSR98b}
Giacobazzi, R., Ranzato, F. and Scozzari, F.  (1998b).
\newblock Complete abstract interpretations made constructive, {\em in}
  J.~Gruska and J.~Zlatuska (eds), {\em Proceedings of 23rd International
  Symposium on Mathematical Foundations of Computer Science (MFCS'98)}, Vol.
  1450 of {\em Lecture Notes in Computer Science}, Springer-Verlag, Berlin,
  pp.~366--377.

\harvarditem[Gierz et al.]{Gierz, Hofmann, Keimel, Lawson, Mislove and
  Scott}{1980}{GHK+80}
Gierz, G., Hofmann, K.~H., Keimel, K., Lawson, J.~D., Mislove, M. and Scott,
  D.~S.  (1980).
\newblock {\em A Compendium of Continuous Lattices}, Springer-Verlag, Berlin.

\harvarditem[Hill et al.]{Hill, Bagnara and Zaffanella}{1998}{HillBZ98b}
Hill, P.~M., Bagnara, R. and Zaffanella, E.  (1998).
\newblock The correctness of set-sharing,  {\em in} \citeasnoun{SAS98},
  pp.~99--114.

\harvarditem[Jacobs and Langen]{Jacobs and Langen}{1989}{JacobsL89}
Jacobs, D. and Langen, A.  (1989).
\newblock Accurate and efficient approximation of variable aliasing in logic
  programs, {\em in} E.~L. Lusk and R.~A. Overbeek (eds), {\em Logic
  Programming: Proceedings of the North American Conference}, MIT Press Series
  in Logic Programming, The MIT Press, Cleveland, Ohio, USA, pp.~154--165.

\harvarditem[Jacobs and Langen]{Jacobs and Langen}{1992}{JacobsL92}
Jacobs, D. and Langen, A.  (1992).
\newblock Static analysis of logic programs for independent {AND} parallelism,
  {\em Journal of Logic Programming} {\bf 13}(2{\&}3):~291--314.

\harvarditem[Jones and S{\o}ndergaard]{Jones and
  S{\o}ndergaard}{1987}{JonesS87}
Jones, N.~D. and S{\o}ndergaard, H.  (1987).
\newblock A semantics-based framework for the abstract interpretation of
  {Prolog}, {\em in} S.~Abramsky and C.~Hankin (eds), {\em Abstract
  Interpretation of Declarative Languages}, Ellis Horwood Ltd, West Sussex,
  England, chapter~6, pp.~123--142.

\harvarditem[Langen]{Langen}{1990}{Langen90th}
Langen, A.  (1990).
\newblock {\em Advanced Techniques for Approximating Variable Aliasing in Logic
  Programs}, PhD thesis, Computer Science Department, University of Southern
  California.
\newblock Printed as Report TR 91-05.

\harvarditem[Levi]{Levi}{1998}{SAS98}
Levi, G. (ed.)  (1998).
\newblock {\em Static Analysis: Proceedings of the 5th International
  Symposium}, Vol. 1503 of {\em Lecture Notes in Computer Science},
  Springer-Verlag, Berlin, Pisa, Italy.

\harvarditem[Scozzari]{Scozzari}{2000}{Scozzari00}
Scozzari, F.  (2000).
\newblock Abstract domains for sharing analysis by optimal semantics, {\em in}
  J.~Palsberg (ed.), {\em Static Analysis: 7th International Symposium, SAS
  2000}, Vol. 1824 of {\em Lecture Notes in Computer Science}, Springer-Verlag,
  Berlin, Santa Barbara, CA, USA, pp.~397--412.

\harvarditem[Scozzari]{Scozzari}{2001}{Scozzari01TCS}
Scozzari, F.  (2001).
\newblock Logical optimality of groundness analysis, {\em Theoretical Computer
  Science}.
\newblock To appear.

\harvarditem[Zaffanella et al.]{Zaffanella, Hill and
  Bagnara}{1999}{ZaffanellaHB99}
Zaffanella, E., Hill, P.~M. and Bagnara, R.  (1999).
\newblock Decomposing non-redundant sharing by complementation, {\em in}
  A.~Cortesi and G.~Fil\'e (eds), {\em Static Analysis: Proceedings of the 6th
  International Symposium}, Vol. 1694 of {\em Lecture Notes in Computer
  Science}, Springer-Verlag, Berlin, Venice, Italy, pp.~69--84.

\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

pst-tree.tex
%% BEGIN pst-tree.tex
%%
%% Trees with PSTricks 97.
%%
\def\fileversion{97 patch 3}
\def\filedate{1997/09/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.
%%
\message{ v\fileversion, \filedate}

\csname PSTreeLoaded\endcsname
\let\PSTreeLoaded\endinput

\ifx\PSTnodesLoaded\endinput\else\input pst-node.tex\fi\relax

\edef\TheAtCode{\the\catcode`\@}
\catcode`\@=11

\newbox\pstree@rootbox
\newbox\pstree@box
\def\pstree@succrow{%
\ifpstreeflip
\def\pssubtree@vertical{\pssubtree@vertical@vflip}%
\else
\def\pssubtree@vertical{\pssubtree@vertical@v}%
\fi
\def\pstree@node{\pstree@node@v}%
\def\pssubtree@horizontal{\pssubtree@horizontal@v}}%
\def\pssubtree@vertical@v{%
\vrule height \pst@dimc depth \pst@dimd width \z@
\ifnum\psnodecnt=\z@
\global\let\pstree@theleftprofile\pstree@leftprofile
\global\let\pstree@therightprofile\pstree@rightprofile
\else
\psk@thistreefit\pstree@therightprofile\pstree@leftprofile
\kern\the\pst@cnth sp
\pstree@zip\pstree@therightprofile
\pstree@rightprofile\pstree@therightprofile
\global\advance\pstree@cnt\pst@cnth
\pst@cnth=\pstree@cnt
\pstree@zip\pstree@leftprofile
\pstree@theleftprofile\pstree@theleftprofile
\fi
\box\pstree@box
\global\advance\psnodecnt 1\relax}%
\def\pssubtree@vertical@vflip{%
\vrule height \pst@dimc depth \pst@dimd width \z@
\ifnum\psnodecnt=\z@
\global\let\pstree@theleftprofile\pstree@leftprofile
\global\let\pstree@therightprofile\pstree@rightprofile
\else
\psk@thistreefit\pstree@theleftprofile\pstree@rightprofile
\kern-\pst@cnth sp
\pstree@zip\pstree@theleftprofile
\pstree@leftprofile\pstree@theleftprofile
\global\advance\pstree@cnt\pst@cnth
\pst@cnth=\pstree@cnt
\pstree@zip\pstree@rightprofile
\pstree@therightprofile\pstree@therightprofile
\fi
\box\pstree@box
\global\advance\psnodecnt 1\relax}%
\def\pstree@node@v{%
\edef\pstree@leftprofile{\psk@thistreenodesize\pst@dima,\pstree@stop,}%
\edef\pstree@rightprofile{\psk@thistreenodesize\pst@dimb,\pstree@stop,}%
\pssubtree@vertical}%
\def\pssubtree@horizontal@v{%
\pstree@max\pstree@upprofile\pst@cntg
\pst@dimc=\pst@cntg sp
\pstree@max\pstree@downprofile\pst@cntg
\pst@dimd=\pst@cntg sp
\pstree@treebboxadjust
\edef\pstree@leftprofile{\number\pst@dima,\pstree@stop,}%
\edef\pstree@rightprofile{\number\pst@dimb,\pstree@stop,}%
\pssubtree@vertical}%
\def\pstree@tightfit#1#2{%
\pst@cnth=\z@
\edef\next{\noexpand\pstree@@tightfit#1\noexpand\@nil#2\noexpand\@nil}%
\next
\advance\pst@cnth\psk@thistreesep\relax
\advance\pst@cnth\pstree@tspace\relax
\gdef\pstree@tspace{\z@}}
\def\pstree@@tightfit#1,#2\@nil#3,#4\@nil{%
\ifnum#1=\pstree@stop
\let\next\relax
\else
\ifnum#3=\pstree@stop
\let\next\relax
\else
\pst@cntg=#1
\advance\pst@cntg#3
\ifnum\pst@cntg>\pst@cnth
\pst@cnth=\pst@cntg
\fi
\def\next{\pstree@@tightfit#2\@nil#4\@nil}%
\fi
\fi
\next}
\def\pstree@loosefit#1#2{%
\pstree@max{#1}\pst@cnth
\pstree@max{#2}\pst@cntg
\advance\pst@cnth\pst@cntg
\advance\pst@cnth\psk@thistreesep\relax
\advance\pst@cnth\pstree@tspace\relax
\gdef\pstree@tspace{\z@}}
\def\tspace#1{%
\pst@@killglue
\pssetlength\pst@dimg{#1}%
\xdef\pstree@tspace{\number\pst@dimg}%
\ignorespaces}
\def\psset@treefit#1{%
\@ifundefined{pstree@#1fit}%
{\@pstrickserr{Bad `treefit' parameter value: `#1'}\@ehpa}%
{\expandafter\let\expandafter\psk@treefit\csname pstree@#1fit\endcsname}}
\psset@treefit{tight}
\def\psset@thistreefit#1{%
\@ifundefined{pstree@#1fit}%
{\@pstrickserr{Bad `treefit' parameter value: `#1'}\@ehpa}%
{\expandafter\let\expandafter\psk@thistreefit
\csname pstree@#1fit\endcsname}}
\psset@treefit{tight}
\def\pstree@zip#1#2#3{%
\def\pst@tempg{}%
\edef\next{\noexpand\pstree@@zip#1\noexpand\@nil#2\noexpand\@nil}%
\next
\global\let#3\pst@tempg}
\def\pstree@@zip#1,#2\@nil#3,#4\@nil{%
\ifnum#1=\pstree@stop
\edef\pst@tempg{\pst@tempg#3,#4}%
\let\next\relax
\else
\ifnum#3=\pstree@stop
\pst@cntg=#1
\advance\pst@cntg-\pst@cnth
\edef\pst@tempg{\pst@tempg\the\pst@cntg,}%
\def\next{\pstree@@zip#2\@nil\pstree@stop,\@nil}%
\else
\edef\pst@tempg{\pst@tempg#3,}%
\def\next{\pstree@@zip#2\@nil#4\@nil}%
\fi
\fi
\next}
\def\pstree@max#1#2{%
\pst@cntg=\z@
\expandafter\pstree@@max#1%
#2=\pst@cntg}%
\def\pstree@@max#1,{%
\ifnum#1=\pstree@stop\else
\ifnum#1>\pst@cntg \pst@cntg=#1 \fi
\expandafter\pstree@@max
\fi}
\def\pstree@add#1{%
\def\pst@tempg{}%
\expandafter\pstree@@add#1%
\xdef#1{\pst@tempg\pstree@stop,}}
\def\pstree@@add#1,{%
\ifnum#1=\pstree@stop\else
\pst@cnth=#1
\advance\pst@cnth\pst@cntg
\xdef\pst@tempg{\pst@tempg\the\pst@cnth,}%
\expandafter\pstree@@add
\fi}
\newcount\psnodecnt
\let\c@psnodecnt\psnodecnt
\newcount\pstreelevel
\let\c@pstreelevel\pstreelevel
\newcount\pstreecnt
\let\c@pstreecnt\pstreecnt
\newcount\pstree@cnt
\def\pstree{\def\pst@par{}\pst@object{pstree}}
\def\pstree@i{\def\pstree@makebox{\pst@@makebox}\pstree@ii}
\def\psTree{\def\pst@par{}\pst@object{psTree}}
\def\psTree@i{\def\pstree@makebox{\pst@makelongbox}\pstree@ii}
\def\endpsTree{\pst@endlongbox\ignorespaces}
\def\pstree@ii{%
\ifnum\pstreelevel=\z@
\let\pstree@savedshortput\pst@shortput
\psset@shortput{tab}%
\else
\pst@@killglue
\fi
\begingroup
\begingroup
\def\pstree@node{%
\xdef\pstree@next{%
\noexpand\@psttrue
\noexpand\def\noexpand\pst@tempa{\number\pst@dima}%
\noexpand\def\noexpand\pst@tempb{\number\pst@dimb}%
\noexpand\def\noexpand\pst@tempc{\number\pst@dimc}%
\noexpand\def\noexpand\pst@tempd{\number\pst@dimd}}%
\box\pstree@box}%
\def\pssubtree@horizontal{\pssubtree@horizontal@o}%
\def\pssubtree@vertical{\pssubtree@vertical@o}%
\global\let\pstree@next\relax
\pst@makebox\pstree@iii}
\def\pstree@iii{%
\global\setbox\pst@boxg=\box\pst@hbox
\endgroup
\setbox\pstree@rootbox=\box\pst@boxg
\@pstfalse
\pstree@next
\if@pst
\ifdim\wd\pstree@rootbox=\z@\else
\@pstrickserr{Extraneous space in root node}\@ehpa
\wd\pstree@rootbox=\z@
\fi
\else
\@pstrickserr{Missing or bad root node
(level \the\pstreelevel, node \the\psnodecnt)}\@ehpa
\def\pstree@next{%
\def\pst@tempa{0}%
\def\pst@tempb{0}%
\def\pst@tempc{0}%
\def\pst@tempd{0}}%
\wd\pstree@rootbox=\z@
\fi
\pstree@savevalues
\begingroup
\pstree@initsuccvalues
\pstree@setlevelpar
\pstree@do}
\def\pstree@setlevelpar{%
\advance\pstreelevel1
\let\psk@thislevelsep\relax
\let\psk@thistreesep\relax
\let\psk@thistreefit\relax
\let\psk@thistreenodesize\relax
\csname pstreehook\romannumeral\pstreelevel\endcsname
\use@par
\ifx\psk@thistreesep\relax
\let\psk@thistreesep\psk@treesep
\fi
\ifx\psk@thistreenodesize\relax
\let\psk@thistreenodesize\psk@treenodesize
\fi
\ifx\psk@thistreefit\relax
\let\psk@thistreefit\psk@treefit
\fi
\ifx\psk@thislevelsep\relax
\let\psk@thislevelsep\psk@levelsep
\let\psk@thislevelsepmode\psk@levelsepmode
\fi
\ifnum\psk@treemode=\pstree@predmode\else
\global\advance\pstreecnt1
\edef\pstree@thetree{\the\pstreecnt}%
\let\pstree@predmode\psk@treemode
\fi
\ifx\psk@thislevelsepmode\relax
\pst@dimg=\psk@thislevelsep\relax
\pst@cntg=0\@nameuse{%
pstree@levelsepadjust-\pstree@thetree-\the\pstreelevel}%
\advance\pst@dimg\pst@cntg sp
\edef\psk@thislevelsep{\number\pst@dimg sp}%
\fi
\ifnum\psk@treemode>1
\def\pst@tposflip{1 sub neg }%
\else
\def\pst@tposflip{}%
\fi
\ifx\pstree@bboxadjust\@empty\else
\xdef\pstree@treebboxadjust{%
\pstree@bboxadjust
\ifpsshowbbox\noexpand\pstree@showbbox\fi}%
\gdef\pstree@bboxadjust{}%
\fi
\let\pst@thispsbox\@skiplevelfalse}
\def\pstree@predmode{-1}
\def\pstree@savevalues{%
\edef\pstree@restorevalues{%
\noexpand\gdef\noexpand\pstree@theleftprofile{\pstree@theleftprofile}%
\noexpand\gdef\noexpand\pstree@therightprofile{\pstree@therightprofile}%
\noexpand\gdef\noexpand\pstree@theupprofile{\pstree@theupprofile}%
\noexpand\gdef\noexpand\pstree@thedownprofile{\pstree@thedownprofile}%
\noexpand\gdef\noexpand\pstree@tspace{\pstree@tspace}%
\noexpand\gdef\noexpand\pssucc{\pssucc}%
\global\psnodecnt=\the\psnodecnt\relax
\global\pstree@cnt=\the\pstree@cnt\relax}%
\let\pstree@savebboxadjust\pstree@treebboxadjust}
\def\pstree@initsuccvalues{%
\def\pstree@therightprofile{\pstree@stop,}%
\let\pstree@theleftprofile\pstree@therightprofile
\let\pstree@theupprofile\pstree@therightprofile
\let\pstree@thedownprofile\pstree@therightprofile
\psnodecnt=\z@
\pstree@cnt\z@
\gdef\pstree@tspace{\z@}%
\let\pspred\pssucc}
\def\pssucc{T}
\pstree@initsuccvalues
\def\pstree@down{%
\pstree@succrow
\pstree@makebox{\pstree@vertical{\lower}}}
\def\pstree@up{%
\pstree@succrow
\pstree@makebox{\pstree@vertical{\raise}}}
\def\pstree@levelsepadjust#1#2{%
% DG/SR modification begin - May 14, 1997 - Patch 1
% Problem with levelsep=*...
%\pst@cntg=0\@nameuse{pstree@levelsepadjust-#1}%
\pst@cntg=0\@nameuse{pstree@levelsepadjust-#1}
% DG/SR modification end
\ifnum#2>\pst@cntg
\expandafter\xdef\csname pstree@levelsepadjust-#1\endcsname
{#2}%
\fi}
\def\pstree@initlevelsepadjust{%
\@ifundefined{@latexerr}{%
\immediate\openin1 \jobname.pst
\ifeof1 \else
\input \jobname.pst
\fi
\immediate\closein1
\csname newwrite\endcsname\pstree@auxout
\immediate\openout\pstree@auxout \jobname.pst }%
{\let\pstree@auxout\@auxout}%
\global\let\pstree@initlevelsepadjust\relax}
\newcount\pstree@stop
\pstree@stop=-987654321
\def\pstree@vertical#1{%
\pst@cntg=\ifpstreeflip-\fi\wd\pst@hbox
\divide\pst@cntg 2
\pstree@add\pstree@theleftprofile
\pstree@add\pstree@therightprofile
\pst@dimg=\psk@thislevelsep\relax
\ifx\psk@thislevelsepmode\relax
\pstree@vertlevelsepadjust{#1}%
\fi
\global\setbox\pstree@box=\hbox{%
\vrule height \pst@tempc sp depth \pst@tempd sp width \z@
\unhbox\pstree@rootbox
#1\pst@dimg\hbox to\z@{\hss\unhbox\pst@hbox\hss}}%
\if@skiplevel
\skiplevel@vertical
\else
\endgroup
\fi
\edef\pstree@leftprofile{\pst@tempa,\pstree@theleftprofile}%
\edef\pstree@rightprofile{\pst@tempb,\pstree@therightprofile}%
\pst@dimc=\ht\pstree@box
\pst@dimd=\dp\pstree@box
\ifpsshowbbox
\pstree@max\pstree@leftprofile\pst@cntg
\pst@dima=\pst@cntg sp
\pstree@max\pstree@rightprofile\pst@cntg
\pst@dimb=\pst@cntg sp
\pstree@showbbox
\fi
\dp\pstree@box=\z@
\ht\pstree@box=\z@
\pstree@restorevalues
\pssubtree@vertical
\global\let\pstree@treebboxadjust\pstree@savebboxadjust
\endgroup
\ifnum\pstreelevel>\z@\expandafter\ignorespaces\fi}
\def\pstree@vertlevelsepadjust#1{%
\ifx\if@filesw\iffalse\else
\ifx#1\lower
\pst@dimh=\pst@tempd sp
\advance\pst@dimh\ht\pst@hbox
\else
\pst@dimh=\pst@tempc sp
\advance\pst@dimh\dp\pst@hbox
\fi
\immediate\write\@auxout{%
\string\pstree@levelsepadjust
{\pstree@thetree-\the\pstreelevel}{\number\pst@dimh}}%
\fi}
\def\pstree@succcolumn{%
\def\pssubtree@vertical{\pssubtree@vertical@h}%
\def\pssubtree@horizontal{\pssubtree@horizontal@h}%
\def\pstree@node{\pstree@node@h}}%
\def\pssubtree@horizontal@h{%
\xdef\pstree@theleftprofile{\number\pst@dima,\pstree@theleftprofile}%
\xdef\pstree@therightprofile{\number\pst@dimb,\pstree@therightprofile}%
\ifnum\psnodecnt=\z@
\global\let\pstree@theupprofile\pstree@upprofile
\global\let\pstree@thedownprofile\pstree@downprofile
\box\pstree@box
\else
\ifpstreeflip
\pssubtree@horizontal@@hflip
\else
\pssubtree@horizontal@@h
\fi
\fi
\global\advance\psnodecnt 1\relax}
\def\pssubtree@horizontal@@h{%
\psk@thistreefit\pstree@thedownprofile\pstree@upprofile
\global\advance\pstree@cnt\pst@cnth
\lower\the\pstree@cnt sp\box\pstree@box
\pstree@zip\pstree@thedownprofile\pstree@downprofile\pstree@thedownprofile
\pst@cnth=\pstree@cnt
\pstree@zip\pstree@upprofile\pstree@theupprofile\pstree@theupprofile}
\def\pssubtree@horizontal@@hflip{%
\psk@thistreefit\pstree@theupprofile\pstree@downprofile
\global\advance\pstree@cnt\pst@cnth
\raise\the\pstree@cnt sp\box\pstree@box
\pstree@zip\pstree@theupprofile\pstree@upprofile\pstree@theupprofile
\pst@cnth=\pstree@cnt
\pstree@zip\pstree@downprofile\pstree@thedownprofile\pstree@thedownprofile}
\def\pstree@node@h{%
\edef\pstree@upprofile{\psk@thistreenodesize\pst@dimc,\pstree@stop,}%
\edef\pstree@downprofile{\psk@thistreenodesize\pst@dimd,\pstree@stop,}%
\pssubtree@horizontal@h}%
\def\pssubtree@vertical@h{%
\pstree@max\pstree@leftprofile\pst@cntg
\pst@dima=\pst@cntg sp
\pstree@max\pstree@rightprofile\pst@cntg
\pst@dimb=\pst@cntg sp
\pstree@treebboxadjust
\edef\pstree@upprofile{\number\pst@dimc,\pstree@stop,}%
\edef\pstree@downprofile{\number\pst@dimd,\pstree@stop,}%
\pssubtree@horizontal@h}%
\newif\if@psrighttree
\def\pstree@right{%
\@psrighttreetrue
\pstree@succcolumn
\pstree@makebox\pstree@horizontal}
\def\pstree@left{%
\@psrighttreefalse
\pstree@succcolumn
\pstree@makebox\pstree@horizontal}
\def\pstree@horizontal{%
\ifdim\wd\pst@hbox=\z@\else
\@pstrickserr{Extraneous space in tree successors}\@ehpa
\fi
\pst@cntg=\ifpstreeflip\ht\else\dp\fi\pst@hbox
\divide\pst@cntg 2
\pstree@add\pstree@theupprofile
\pstree@add\pstree@thedownprofile
% DG/SR modification begin - Sep. 24, 1997 - Patch 3
%\ifx\psk@thislevelsepmode\relax
%\pstree@horizlevelsepadjust
%\fi
% DG/SR modification end
\pst@dimg\psk@thislevelsep\relax
\global\setbox\pstree@box=\hbox{%
\unhbox\pstree@rootbox
\kern\if@psrighttree\else-\fi\pst@dimg
\ifpstreeflip\lower\else\raise\fi\pst@cntg sp\box\pst@hbox}%
% DG/SR modification begin - Sep. 24, 1997 - Patch 3
\ifx\psk@thislevelsepmode\relax
\pstree@horizlevelsepadjust
\fi
% DG/SR modification end
\if@psrighttree
\pst@dimh=\pst@dimg
\pstree@max\pstree@therightprofile\pst@cntg
\global\advance\pst@dimh\pst@cntg sp
\global\pst@dimg=\pst@tempa sp
\else
\pstree@max\pstree@theleftprofile\pst@cntg
\global\advance\pst@dimg\pst@cntg sp
\global\pst@dimh=\pst@tempb sp
\fi
\if@skiplevel
\skiplevel@horizontal
\else
\endgroup
\fi
\pst@dima=\pst@dimg
\pst@dimb=\pst@dimh
\edef\pstree@upprofile{\pst@tempc,\pstree@theupprofile}%
\edef\pstree@downprofile{\pst@tempd,\pstree@thedownprofile}%
\dp\pstree@box=\z@
\ht\pstree@box=\z@
\wd\pstree@box=\z@
\ifpsshowbbox
\pstree@max\pstree@upprofile\pst@cntg
\pst@dimc=\pst@cntg sp
\pstree@max\pstree@downprofile\pst@cntg
\pst@dimd=\pst@cntg sp
\pstree@showbbox
\fi
\pstree@restorevalues
\pssubtree@horizontal
\endgroup
\ifnum\pstreelevel>\z@\expandafter\ignorespaces\fi}
% DG/SR modification begin - Sep. 24, 1997 - Patch 2
%\def\pstree@horizlevelsepadjust#1{%
\def\pstree@horizlevelsepadjust{%
% DG/SR modification end
\ifx\if@filesw\iffalse\else
\if@psrighttree
\pst@dimh=\pst@tempb sp
\pstree@max\pstree@theleftprofile\pst@cntg
\advance\pst@dimh\pst@cntg sp
\else
\pst@dimh=\pst@tempa sp
\pstree@max\pstree@therightprofile\pst@cntg
\advance\pst@dimh\pst@cntg sp
\fi
\immediate\write\@auxout{%
\string\pstree@levelsepadjust
{\pstree@thetree-\the\pstreelevel}{\number\pst@dimh}}%
\fi}
\def\psset@treemode#1{%
\pst@cntg=
\ifx#1U\@empty2\else\ifx#1R\@empty1\else\ifx#1L\@empty3\else0\fi\fi\fi
\relax
\edef\psk@treemode{\the\pst@cntg}%
\ifcase\pst@cntg
\let\pstree@do\pstree@down
\or
\let\pstree@do\pstree@right
\or
\let\pstree@do\pstree@up
\or
\let\pstree@do\pstree@left
\fi}
\def\psk@treemode{0}
\let\pstree@do\pstree@down
\def\psset@treesep#1{%
\pssetlength\pst@dimg{#1}%
\edef\psk@treesep{\number\pst@dimg}}%
\psset@treesep{.75cm}
\def\psset@thistreesep#1{%
\pssetlength\pst@dimg{#1}%
\edef\psk@thistreesep{\number\pst@dimg}}%
\def\psset@treenodesize#1{%
\pssetlength\pst@dimg{#1}%
\ifdim\pst@dimg<\z@
\let\psk@treenodesize\number
\else
\edef\psk@treenodesize{\number\pst@dimg\noexpand\@gobble}%
\fi}
\psset@treenodesize{-1pt}
\def\psset@thistreenodesize#1{%
\pssetlength\pst@dimg{#1}%
\ifdim\pst@dimg<\z@
\let\psk@thistreenodesize\number
\else
\edef\psk@thistreenodesize{\number\pst@dimg\noexpand\@gobble}%
\fi}
\def\psset@levelsep#1{%
\pst@expandafter{\pst@ifstar\psset@@levelsep}{#1}\@nil}
\def\psset@@levelsep#1\@nil{%
\pst@@getlength{#1}\psk@levelsep
\if@star
\pstree@initlevelsepadjust
\let\psk@levelsepmode\relax
\else
\def\psk@levelsepmode{}%
\fi}
\psset@levelsep{2cm}
\def\psset@thislevelsep#1{%
\pst@expandafter{\pst@ifstar\psset@@thislevelsep}{#1}\@nil}
\def\psset@@thislevelsep#1\@nil{%
\pst@@getlength{#1}\psk@thislevelsep
\if@star
\pstree@initlevelsepadjust
\let\psk@thislevelsepmode\relax
\else
\def\psk@thislevelsepmode{}%
\fi}
\newif\ifpstreeflip
\def\psset@treeflip#1{\@nameuse{pstreeflip#1}}
\psset@treeflip{false}
\def\pstree@node@o{%
\leavevmode
\hbox{%
\vrule height \pst@dimc depth \pst@dimd width \z@
\kern\pst@dima
\box\pstree@box
\kern\pst@dimb}}
\def\pssubtree@vertical@o{%
\pstree@max\pstree@leftprofile\pst@cntg
\pst@dima=\pst@cntg sp
\pstree@max\pstree@rightprofile\pst@cntg
\pst@dimb=\pst@cntg sp
\pstree@treebboxadjust
\pstree@node}
\def\pssubtree@horizontal@o{%
\pstree@max\pstree@upprofile\pst@cntg
\pst@dimc=\pst@cntg sp
\pstree@max\pstree@downprofile\pst@cntg
\pst@dimd=\pst@cntg sp
\pstree@treebboxadjust
\pstree@node}
\def\pstree@outer{%
\def\pstree@node{\pstree@node@o}%
\def\pssubtree@vertical{\pssubtree@vertical@o}%
\def\pssubtree@horizontal{\pssubtree@horizontal@o}%
\pstreelevel=\z@
\def\pstree@predmode{-1}%
\def\pst@tposflip{}%
\let\pst@thisbox\relax
\let\pst@shortput\pstree@savedshortput}
\let\pstree@savedshortput\ignorespaces
\pstree@outer
\newif\ifpsshowbbox
\def\psset@showbbox#1{\@nameuse{psshowbbox#1}}%
\psset@showbbox{false}
\def\pstree@showbbox{%
\setbox\pstree@box=\hbox{%
\psframe[linewidth=0,linecolor=black,linestyle=solid,fillstyle=none]%
(-\pst@dima,-\pst@dimd)(\pst@dimb,\pst@dimc)%
\box\pstree@box}}%
\def\psset@edge#1{%
\def\psedge{#1}%
\ifx\psedge\@none
\def\psedge##1##2{}%
\fi}
\psset@edge{\ncline}
\def\pspred{T}
\def\pstree@makenodebox{%
\pst@@killglue
\let\pst@thispsbox\pstree@outer
\pst@makebox}
\def\begin@treenode{%
\pst@@killglue
\begingroup
\use@par
\global\let\pstree@edge\psedge
\xdef\pssucc{\pspred-\the\psnodecnt}}
\def\MakeShortTnput#1{%
\def\end@treenode{\@ifnextchar#1{\tnput@}{\end@@treenode}}}
\MakeShortTnput{~}
\def\end@@treenode{%
\pstree@bboxadjust
\gdef\pstree@bboxadjust{}%
\ifpsshowbbox\pstree@showbbox\fi
\pstree@node
\endgroup
\ifnum\pstreelevel>\z@
\pstree@edge{\pspred}{\pssucc}%
\expandafter\pst@shortput
\else
\expandafter\ignorespaces
\fi}
\def\pstree@bboxadjust{}
\def\pstree@setbboxadjust#1#2{%
\pssetlength\pst@dimg{#1}%
\xdef\pstree@bboxadjust{%
\pstree@bboxadjust
#2\number\pst@dimg sp\relax}}
\def\psset@bbl#1{\pstree@setbboxadjust{#1}{\pst@dima=}}
\def\psset@bbr#1{\pstree@setbboxadjust{#1}{\pst@dimb=}}
\def\psset@bbh#1{\pstree@setbboxadjust{#1}{\pst@dimc=}}
\def\psset@bbd#1{\pstree@setbboxadjust{#1}{\pst@dimd=}}
\def\psset@xbbl#1{\pstree@setbboxadjust{#1}{\advance\pst@dima}}
\def\psset@xbbr#1{\pstree@setbboxadjust{#1}{\advance\pst@dimb}}
\def\psset@xbbh#1{\pstree@setbboxadjust{#1}{\advance\pst@dimc}}
\def\psset@xbbd#1{\pstree@setbboxadjust{#1}{\advance\pst@dimd}}
\let\pstree@treebboxadjust\relax
\def\Tn{\def\pst@par{}\pst@object{Tn}}
\def\Tn@i{%
\pst@@killglue
\global\let\pssucc\pspred
\begingroup
\pst@dima=\z@
\pst@dimb=\z@
\pst@dimc=\z@
\pst@dimd=\z@
\setbox\pstree@box=\hbox{}%%
\pstree@node
\endgroup
\ignorespaces}
\def\Tp{\def\pst@par{}\pst@object{Tp}}
\def\Tp@i{%
\begin@treenode
\pst@dima=\z@
\pst@dimb=\z@
\pst@dimc=\z@
\pst@dimd=\z@
\setbox\pstree@box=\hbox{%
\pst@newnode{\pssucc}{10}{0 0 }{\tx@InitPnode}}%
\end@treenode}
\def\Tc{\def\pst@par{}\pst@object{Tc}}
\def\Tc@i#1{%
\begin@treenode
\pssetlength\pst@dima{#1}%
\pst@dimb=\pst@dima
\pst@dimc=\pst@dima
\pst@dimd=\pst@dima
\nodealignfalse
\setbox\pstree@box=\hbox{\cnode@ii(\z@,\z@){#1}{\pssucc}}%
\end@treenode}
\def\TC{\def\pst@par{}\pst@object{TC}}
\def\TC@i{\Tc@i{\psk@radius}}
\def\Toval{\def\pst@par{}\pst@object{Toval}}
\def\Toval@i{\pstree@makenodebox{\Toval@ii\ovalnode@ii}}
\def\Toval@ii#1{%
\begin@treenode
\nodealigntrue
\setbox\pstree@box=\hbox{#1\pssucc}%
\pst@dima=\wd\pstree@box
\divide\pst@dima 2
\pst@dimb=\pst@dima
\pst@dimc=\ht\pstree@box
\pst@dimd=\dp\pstree@box
\setbox\pstree@box=\hbox to\z@{\hss\unhbox\pstree@box\hss}%
\dp\pstree@box=\z@
\ht\pstree@box=\z@
\end@treenode}
\def\Tcircle{\def\pst@par{}\pst@object{Tcircle}}
\def\Tcircle@i{\pstree@makenodebox{\Toval@ii\circlenode@ii}}
\def\Tf{\def\pst@par{}\pst@object{Tf}}
\def\Tf@i{\Toval@ii{\fnode@ii()}}
\def\Tdia{\def\pst@par{}\pst@object{Tdia}}
\def\Tdia@i{\pstree@makenodebox{\Toval@ii\dianode@ii}}
\def\Ttri{\def\pst@par{}\pst@object{Ttri}}
\def\Ttri@i{\pstree@makenodebox{\Ttri@ii}}
\def\Ttri@ii{%
\begin@treenode
\nodealigntrue
\setbox\pstree@box=\hbox{\trinode@ii\pssucc}%
\pst@dima=\pst@dimg % Set by \pst@triboxsep
\pst@dimb=\wd\pstree@box
\advance\pst@dimb-\pst@dima
\pst@dimc=\ht\pstree@box
\pst@dimd=\dp\pstree@box
\setbox\pstree@box=\hbox to\z@{\hss\unhbox\pstree@box\hss}%
\dp\pstree@box=\z@
\ht\pstree@box=\z@
\end@treenode}
\def\Tr{\def\pst@par{}\pst@object{Tr}}
% SR modification begin - Oct. 27, 1996
%\def\Tr@i{\pstree@makenodebox{\Tr@ii{\begingroup\rnode@ii}}}
\def\Tr@i{\pstree@makenodebox{\Tr@ii{\rnode@iii\rnode@iv}}}
% SR modification end
\def\Tr@ii#1{%
\begin@treenode
\def\pstree@nodehook{%
\xdef\pstree@next{\pst@dima=\number\pst@dima sp\relax}}%
\nodealigntrue
\setbox\pstree@box\hbox{#1\pssucc}%
\pstree@next
\pst@dimb=\wd\pstree@box
\advance\pst@dimb-\pst@dima
\pst@dimc=\ht\pstree@box
\pst@dimd=\dp\pstree@box
\setbox\pstree@box\hbox to\z@{\kern-\pst@dima\unhbox\pstree@box\hss}%
\ht\pstree@box=\z@
\dp\pstree@box=\z@
\end@treenode}
\def\TR{\def\pst@par{}\pst@object{TR}}
% DG modification begin - Oct. 25, 1996
%\def\TR@i{\pstree@makenodebox{\Tr@ii{\Rnode@ii}}}
\def\TR@i{\pstree@makenodebox{\Tr@ii{\rnode@iii\Rnode@ii}}}
% DG modification end
\def\Tdot{\def\pst@par{}\pst@object{Tdot}}
\def\Tdot@i{%
\begin@treenode
\def\pstree@nodehook{\xdef\pstree@next{%
\pst@dima=\number\pst@dima sp\relax
\pst@dimc=\number\pst@dimb sp\relax}}%
\nodealignfalse
\setbox\pstree@box=\hbox{\dotnode@ii(\z@,\z@)\pssucc}%
\pstree@next
\pst@dimb=\pst@dima
\pst@dimd=\pst@dimc
\end@treenode}
\def\psset@fansize#1{\pst@@getlength{#1}\psk@fansize}
\psset@fansize{1cm}
\def\Tfan{\def\pst@par{}\pst@object{Tfan}}
\def\Tfan@i{%
\addto@par{edge=none}%
\begin@treenode
\solid@star
\pst@dimb=\psk@fansize
\pst@dimd=\pslinewidth
\advance\pst@dimb-\pst@dimd
\divide\pst@dimb 2
\divide\pst@dimd 2
\ifodd\psk@treemode\relax
\pst@dima=\pst@dimd
\pst@dimc=\pst@dimb
\else
\pst@dima=\pst@dimb
\pst@dimc=\pst@dimd
\fi
\setbox\pstree@box=\hbox{%
\pst@newnode{\pssucc}{16}{}{%
/Y 0 def
/X 0 def
/l \pst@number\pst@dima def
/r l def
/u \pst@number\pst@dimc def
/d u def
/NodePos { \tx@GetRnodePos } def}%
\def\pst@linetype{1}%
\nc@object{Closed}{\pspred}{\pssucc}{.5}{%
tx@Dict begin \psline@iii pop end
/w \pst@number\pst@dimb CLW 2 div sub def
/m \ifodd\psk@treemode false \else true \fi def
\tx@Tfan}}%
\pst@dimb=\pst@dima
\pst@dimd=\pst@dimc
\end@treenode}
\def\psset@tnsep#1{%
\def\pst@tempg{#1}%
\ifx\pst@tempg\@empty
\def\psk@tnsep{\number\pslabelsep sp}%
\else
\pst@@getlength{#1}\psk@tnsep
\fi}
\psset@tnsep{}
\def\psset@tnyref#1{\def\psk@tnyref{#1}}%
\psset@tnyref{}
\def\psset@tnheight#1{\edef\psk@tnheight{#1}}
\psset@tnheight{\ht\strutbox}
\def\psset@tndepth#1{\edef\psk@tndepth{#1}}
\psset@tndepth{\dp\strutbox}
\def\psset@tnpos#1{%
\def\pst@tempg{#1}%
\ifx\pst@tempg\@empty
\def\psk@tnpos{%
\ifcase\psk@treemode b\or r\or a\or l\fi}%
\else
\@ifundefined{pstree@tnput@#1}%
{\@pstrickserr{Bad tnpos: `#1'}\@ehpa}%
{\edef\psk@tnpos{#1}}%
\fi}
\psset@tnpos{}
\def\tnput@#1{\def\pst@par{}\pst@object{tnput}}
\def\tnput@i{\pstree@makenodebox{\tnput@ii}}
\def\tnput@ii{%
\begingroup
\use@par
\xdef\next{%
\if@star\noexpand\pst@starbox\fi
\noexpand\def\noexpand\psk@thistndepth{\psk@tndepth}%
\noexpand\def\noexpand\psk@thistnheight{\psk@tnheight}%
\noexpand\def\noexpand\psk@thistnyref{\psk@tnyref}%
\noexpand\def\noexpand\psk@thistnsep{\psk@tnsep}%
\expandafter\noexpand\csname pstree@tnput@\psk@tnpos\endcsname}%
\endgroup
\next
\end@treenode}
\@namedef{pstree@tnput@b}{%
\pstree@tnput@@v\pst@dimd\ht\dp\lower\psk@thistnheight}
\@namedef{pstree@tnput@a}{%
\pstree@tnput@@v\pst@dimc\dp\ht\raise\psk@thistndepth}
\def\pstree@tnput@@v#1#2#3#4#5{%
\pst@dimh=\wd\pst@hbox
\pst@dimg=\psk@href\pst@dimh
\advance\pst@dimg\pst@dimh
\divide\pst@dimg 2
\advance\pst@dimh-\pst@dimg
\ifdim\pst@dimg>\pst@dima
\pst@dima=\pst@dimg
\fi
\ifdim\pst@dimh>\pst@dimb
\pst@dimb=\pst@dimh
\fi
\pst@dimh=\psk@thistnsep\relax
\ifdim\pst@dimh<\z@
\pst@dimh=-\pst@dimh
\else
\advance\pst@dimh#1%
\fi
\pssetlength\dimen@{#5}%
\ifdim\dimen@>#2\pst@hbox
\advance\pst@dimh\dimen@\relax
\else
\advance\pst@dimh#2\pst@hbox
\fi
\setbox\pstree@box=\hbox{%
\box\pstree@box
#4\pst@dimh\hbox to\z@{\kern-\pst@dimg\unhbox\pst@hbox\hss}}%
#1=#3\pstree@box
\dp\pstree@box=\z@
\ht\pstree@box=\z@}
\@namedef{pstree@tnput@l}{%
\pstree@tnput@@h\pst@dima{%
\hss
\lower\pst@dimg\box\pst@hbox
\kern\pst@dimh
\box\pstree@box}}
\@namedef{pstree@tnput@r}{%
\pstree@tnput@@h\pst@dimb{%
\box\pstree@box
\kern\pst@dimh
\lower\pst@dimg\box\pst@hbox
\hss}}%
\def\pstree@tnput@@h#1#2{%
\ifx\psk@thistnyref\@empty
\pssetlength\pst@dimg\psk@vref
\else
\pst@dimg=\ht\pst@hbox
\advance\pst@dimg\dp\pst@hbox
\pst@dimg=\psk@thistnyref\pst@dimg
\advance\pst@dimg-\dp\pst@hbox
\fi
\pst@dimh=\psk@thistnsep\relax
\ifdim\pst@dimh<\z@
\pst@dimh=-\pst@dimh
\else
\advance\pst@dimh#1%
\fi
#1=\pst@dimh
\advance#1\wd\pst@hbox
\setbox\pstree@box=\hbox to\z@{#2}%
\ifdim\ht\pstree@box>\pst@dimc
\pst@dimc=\ht\pstree@box
\fi
\ifdim\dp\pstree@box>\pst@dimd
\pst@dimd=\dp\pstree@box
\fi
\dp\pstree@box=\z@
\ht\pstree@box=\z@}
\newif\if@skiplevel
\def\skiplevel{\def\pst@par{}\pst@object{skiplevel}}
\def\skiplevel@i{\def\pstree@makebox{\pst@@makebox}\skiplevel@ii}
\def\skiplevel@ii{%
\pst@@killglue
\begingroup
\let\pssucc\pspred
\def\pst@tempa{0}%
\def\pst@tempb{0}%
\def\pst@tempc{0}%
\def\pst@tempd{0}%
\setbox\pstree@rootbox=\hbox{}%
\pstree@savevalues
\begingroup
\pstree@initsuccvalues
\pstree@setlevelpar
\@skipleveltrue
\pstree@do}
\def\pstree@gettop#1{\expandafter\pstree@@gettop#1\@nil}
\def\pstree@@gettop#1,#2\@nil{#1}
\def\skiplevel@horizontal{%
\pst@dimc=\pstree@gettop\pstree@theupprofile sp
\pst@dimd=\pstree@gettop\pstree@thedownprofile sp
\pstree@treebboxadjust
\gdef\pstree@treebboxadjust{}%
\xdef\pstree@next{%
\noexpand\def\noexpand\pst@tempc{\number\pst@dimc}%
\noexpand\def\noexpand\pst@tempd{\number\pst@dimd}}%
\endgroup
\pstree@next}
\def\skiplevel@vertical{%
\pst@dima=\pstree@gettop\pstree@theleftprofile sp
\pst@dimb=\pstree@gettop\pstree@therightprofile sp
\pstree@treebboxadjust
\gdef\pstree@treebboxadjust{}%
\xdef\pstree@next{%
\noexpand\def\noexpand\pst@tempa{\number\pst@dima}%
\noexpand\def\noexpand\pst@tempb{\number\pst@dimb}}%
\endgroup
\pstree@next}
\def\skiplevels{\def\pst@par{}\pst@object{skiplevels}}
\def\skiplevels@i#1{%
\pst@@killglue
\begingroup
\pst@cnta=#1\relax
\edef\skiplevels@num{\the\pst@cnta}%
\def\pstree@makebox{\pst@makelongbox}%
\def\endskiplevels{}%
\loop
\ifnum\pst@cnta>\z@
\advance\pst@cnta-1
\expandafter\def\expandafter\endskiplevels\expandafter{%
\endskiplevels\pst@endlongbox}
\skiplevel@ii
\repeat
\expandafter\def\expandafter\endskiplevels\expandafter{%
\endskiplevels\endgroup\ignorespaces}
\ignorespaces}

\catcode`\@=\TheAtCode\relax

\endinput
%%
%% END: pst-tree.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

cs0101025.extracted_bib
\begin{thebibliography}{xx}

\harvarditem[Armstrong et al.]{Armstrong, Marriott, Schachte and
  S{\o}ndergaard}{1998}{ArmstrongMSS98}
Armstrong, T., Marriott, K., Schachte, P. and S{\o}ndergaard, H.  (1998).
\newblock Two classes of {Boolean} functions for dependency analysis, {\em
  Science of Computer Programming} {\bf 31}(1):~3--45.

\harvarditem[Bagnara and Schachte]{Bagnara and Schachte}{1999}{BagnaraS99}
Bagnara, R. and Schachte, P.  (1999).
\newblock Factorizing equivalent variable pairs in {ROBDD}-based
  implementations of \textit{Pos}, {\em in} A.~M. Haeberer (ed.), {\em
  Proceedings of the ``Seventh International Conference on Algebraic
  Methodology and Software Technology (AMAST'98)''}, Vol. 1548 of {\em Lecture
  Notes in Computer Science}, Springer-Verlag, Berlin, Amazonia, Brazil,
  pp.~471--485.

\harvarditem[Bagnara et al.]{Bagnara, Hill and Zaffanella}{1997}{BagnaraHZ97b}
Bagnara, R., Hill, P.~M. and Zaffanella, E.  (1997).
\newblock Set-sharing is redundant for pair-sharing, {\em in} P.~{Van
  Hentenryck} (ed.), {\em Static Analysis: Proceedings of the 4th International
  Symposium}, Vol. 1302 of {\em Lecture Notes in Computer Science},
  Springer-Verlag, Berlin, Paris, France, pp.~53--67.

\harvarditem[Bagnara et al.]{Bagnara, Hill and
  Zaffanella}{2001}{BagnaraHZ01TCS}
Bagnara, R., Hill, P.~M. and Zaffanella, E.  (2001).
\newblock Set-sharing is redundant for pair-sharing, {\em Theoretical Computer
  Science}.
\newblock To appear.

\harvarditem[Codish and S{\o}ndergaard]{Codish and
  S{\o}ndergaard}{1998}{CodishS98}
Codish, M. and S{\o}ndergaard, H.  (1998).
\newblock The {Boolean} logic of set sharing analysis, {\em in} C.~Palamidessi,
  H.~Glaser and K.~Meinke (eds), {\em Principles of Declarative Programming},
  Vol. 1490 of {\em Lecture Notes in Computer Science}, Springer-Verlag,
  Berlin, Pisa, Italy, pp.~89--100.

\harvarditem[Colmerauer]{Colmerauer}{1982}{Colmerauer82}
Colmerauer, A.  (1982).
\newblock {Prolog} and infinite trees, {\em in} K.~L. Clark and S.~{\AA}.
  T{\"a}rnlund (eds), {\em Logic Programming, APIC Studies in Data Processing},
  Vol.~16, Academic {P}ress, New York, pp.~231--251.

\harvarditem[Colmerauer]{Colmerauer}{1984}{Colmerauer84}
Colmerauer, A.  (1984).
\newblock Equations and inequations on finite and infinite trees, {\em
  Proceedings of the International Conference on Fifth Generation Computer
  Systems (FGCS'84)}, ICOT, Tokyo, Japan, pp.~85--99.

\harvarditem[Cortesi and Fil\'e]{Cortesi and Fil\'e}{1999}{CortesiF99}
Cortesi, A. and Fil\'e, G.  (1999).
\newblock Sharing is optimal, {\em Journal of Logic Programming} {\bf
  38}(3):~371--386.

\harvarditem[Cortesi et al.]{Cortesi, Fil\'e and
  Winsborough}{1994}{CortesiFW94}
Cortesi, A., Fil\'e, G. and Winsborough, W.  (1994).
\newblock The quotient of an abstract interpretation for comparing static
  analyses, {\em in} M.~Alpuente, R.~Barbuti and I.~Ramos (eds), {\em
  Proceedings of the ``1994 Joint Conference on Declarative Programming
  (GULP-PRODE'94)''}, Pe\~n\'{\i}scola, Spain, pp.~372--397.
\newblock An extended version has been published as \cite{CortesiFW98}.

\harvarditem[Cortesi et al.]{Cortesi, Fil\'e and
  Winsborough}{1996}{CortesiFW96}
Cortesi, A., Fil\'e, G. and Winsborough, W.  (1996).
\newblock Optimal groundness analysis using propositional logic, {\em Journal
  of Logic Programming} {\bf 27}(2):~137--167.

\harvarditem[Cortesi et al.]{Cortesi, Fil\'e and
  Winsborough}{1998}{CortesiFW98}
Cortesi, A., Fil\'e, G. and Winsborough, W.  (1998).
\newblock The quotient of an abstract interpretation for comparing static
  analyses, {\em Theoretical Computer Science} {\bf 202}(1{\&}2):~163--192.

\harvarditem[Cortesi et al.]{Cortesi, Fil\'e, Giacobazzi, Palamidessi and
  Ranzato}{1995}{CortesiFGPR95}
Cortesi, A., Fil\'e, G., Giacobazzi, R., Palamidessi, C. and Ranzato, F.
  (1995).
\newblock Complementation in abstract interpretation, {\em in} A.~Mycroft
  (ed.), {\em Static Analysis: Proceedings of the 2nd International Symposium},
  Vol. 983 of {\em Lecture Notes in Computer Science}, Springer-Verlag, Berlin,
  Glasgow, UK, pp.~100--117.

\harvarditem[Cortesi et al.]{Cortesi, Fil\'e, Giacobazzi, Palamidessi and
  Ranzato}{1997}{CortesiFGPR97}
Cortesi, A., Fil\'e, G., Giacobazzi, R., Palamidessi, C. and Ranzato, F.
  (1997).
\newblock Complementation in abstract interpretation, {\em ACM Transactions on
  Programming Languages and Systems} {\bf 19}(1):~7--47.

\harvarditem[Cousot and Cousot]{Cousot and Cousot}{1979}{CousotC79}
Cousot, P. and Cousot, R.  (1979).
\newblock Systematic design of program analysis frameworks, {\em Proceedings of
  the Sixth Annual ACM Symposium on Principles of Programming Languages},
  pp.~269--282.

\harvarditem[Fil\'e and Ranzato]{Fil\'e and Ranzato}{1996}{FileR96}
Fil\'e, G. and Ranzato, F.  (1996).
\newblock Complementation of abstract domains made easy, {\em in} M.~Maher
  (ed.), {\em Logic Programming: Proceedings of the Joint International
  Conference and Symposium on Logic Programming}, MIT Press Series in Logic
  Programming, The MIT Press, Bonn, Germany, pp.~348--362.

\harvarditem[Giacobazzi and Ranzato]{Giacobazzi and
  Ranzato}{1997}{GiacobazziR97}
Giacobazzi, R. and Ranzato, F.  (1997).
\newblock Completeness in abstract interpretation: a domain perspective, {\em
  in} M.~Johnson (ed.), {\em Proceedings of the 6th International Conference on
  Algebraic Methodology and Software Technology (AMAST'97)}, Vol. 1349 of {\em
  Lecture Notes in Computer Science}, Springer-Verlag, Berlin, Sydney,
  Australia, pp.~231--245.

\harvarditem[Giacobazzi et al.]{Giacobazzi, Ranzato and
  Scozzari}{1998a}{GiacobazziSR98a}
Giacobazzi, R., Ranzato, F. and Scozzari, F.  (1998a).
\newblock Building complete abstract interpretations in a linear logic-based
  setting,  {\em in} \citeasnoun{SAS98}, pp.~215--229.

\harvarditem[Giacobazzi et al.]{Giacobazzi, Ranzato and
  Scozzari}{1998b}{GiacobazziSR98b}
Giacobazzi, R., Ranzato, F. and Scozzari, F.  (1998b).
\newblock Complete abstract interpretations made constructive, {\em in}
  J.~Gruska and J.~Zlatuska (eds), {\em Proceedings of 23rd International
  Symposium on Mathematical Foundations of Computer Science (MFCS'98)}, Vol.
  1450 of {\em Lecture Notes in Computer Science}, Springer-Verlag, Berlin,
  pp.~366--377.

\harvarditem[Gierz et al.]{Gierz, Hofmann, Keimel, Lawson, Mislove and
  Scott}{1980}{GHK+80}
Gierz, G., Hofmann, K.~H., Keimel, K., Lawson, J.~D., Mislove, M. and Scott,
  D.~S.  (1980).
\newblock {\em A Compendium of Continuous Lattices}, Springer-Verlag, Berlin.

\harvarditem[Hill et al.]{Hill, Bagnara and Zaffanella}{1998}{HillBZ98b}
Hill, P.~M., Bagnara, R. and Zaffanella, E.  (1998).
\newblock The correctness of set-sharing,  {\em in} \citeasnoun{SAS98},
  pp.~99--114.

\harvarditem[Jacobs and Langen]{Jacobs and Langen}{1989}{JacobsL89}
Jacobs, D. and Langen, A.  (1989).
\newblock Accurate and efficient approximation of variable aliasing in logic
  programs, {\em in} E.~L. Lusk and R.~A. Overbeek (eds), {\em Logic
  Programming: Proceedings of the North American Conference}, MIT Press Series
  in Logic Programming, The MIT Press, Cleveland, Ohio, USA, pp.~154--165.

\harvarditem[Jacobs and Langen]{Jacobs and Langen}{1992}{JacobsL92}
Jacobs, D. and Langen, A.  (1992).
\newblock Static analysis of logic programs for independent {AND} parallelism,
  {\em Journal of Logic Programming} {\bf 13}(2{\&}3):~291--314.

\harvarditem[Jones and S{\o}ndergaard]{Jones and
  S{\o}ndergaard}{1987}{JonesS87}
Jones, N.~D. and S{\o}ndergaard, H.  (1987).
\newblock A semantics-based framework for the abstract interpretation of
  {Prolog}, {\em in} S.~Abramsky and C.~Hankin (eds), {\em Abstract
  Interpretation of Declarative Languages}, Ellis Horwood Ltd, West Sussex,
  England, chapter~6, pp.~123--142.

\harvarditem[Langen]{Langen}{1990}{Langen90th}
Langen, A.  (1990).
\newblock {\em Advanced Techniques for Approximating Variable Aliasing in Logic
  Programs}, PhD thesis, Computer Science Department, University of Southern
  California.
\newblock Printed as Report TR 91-05.

\harvarditem[Levi]{Levi}{1998}{SAS98}
Levi, G. (ed.)  (1998).
\newblock {\em Static Analysis: Proceedings of the 5th International
  Symposium}, Vol. 1503 of {\em Lecture Notes in Computer Science},
  Springer-Verlag, Berlin, Pisa, Italy.

\harvarditem[Scozzari]{Scozzari}{2000}{Scozzari00}
Scozzari, F.  (2000).
\newblock Abstract domains for sharing analysis by optimal semantics, {\em in}
  J.~Palsberg (ed.), {\em Static Analysis: 7th International Symposium, SAS
  2000}, Vol. 1824 of {\em Lecture Notes in Computer Science}, Springer-Verlag,
  Berlin, Santa Barbara, CA, USA, pp.~397--412.

\harvarditem[Scozzari]{Scozzari}{2001}{Scozzari01TCS}
Scozzari, F.  (2001).
\newblock Logical optimality of groundness analysis, {\em Theoretical Computer
  Science}.
\newblock To appear.

\harvarditem[Zaffanella et al.]{Zaffanella, Hill and
  Bagnara}{1999}{ZaffanellaHB99}
Zaffanella, E., Hill, P.~M. and Bagnara, R.  (1999).
\newblock Decomposing non-redundant sharing by complementation, {\em in}
  A.~Cortesi and G.~Fil\'e (eds), {\em Static Analysis: Proceedings of the 6th
  International Symposium}, Vol. 1694 of {\em Lecture Notes in Computer
  Science}, Springer-Verlag, Berlin, Venice, Italy, pp.~69--84.

\end{thebibliography}