% \iffalse meta-comment
%
% expressg.dtx
% Author: Peter Wilson (CUA) now at peter.r.wilson@boeing.com until June 2004
%                            (or: pandgwilson at earthlink dot net) 
% Copyright 1996, 2003, 2004 Peter R. Wilson
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3 of this license or (at your option) any 
% later version.
% The latest version of the license is in
%    http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of
% LaTeX version 2003/06/01 or later.
%
% This work has the LPPL maintenance status "author-maintained".
%
% This work consists of the files listed in the README file.
%
% If you do not have the docmfp package (available from CTAN in
% tex-archive/macros/latex/contrib/supported), comment out the
% \usepackage{docmfp} line below and uncomment the line following it.
% 
%<*driver>
\documentclass{ltxdoc}
\usepackage{docmfp}
%%%% \newenvironment{variable}[1]{}{} \newenvironment{routine}[1]{}{}
\providecommand{\DescribeVariable}[1]{} \providecommand{\DescribeRoutine}[1]{}
\providecommand{\variablestring}{} \renewcommand{\variablestring}{\space(v)}
\providecommand{\routinestring}{} \renewcommand{\routinestring}{\space(r)}
\EnableCrossrefs
\CodelineIndex
\setcounter{StandardModuleDepth}{1}

\begin{document}
  \DocInput{expressg.dtx}
\end{document}
%</driver>
%
% \fi
%
% \CheckSum{171}
%
% \DoNotIndex{\',\.,\@M,\@@input,\@addtoreset,\@arabic,\@badmath}
% \DoNotIndex{\@centercr,\@cite}
% \DoNotIndex{\@dotsep,\@empty,\@float,\@gobble,\@gobbletwo,\@ignoretrue}
% \DoNotIndex{\@input,\@ixpt,\@m}
% \DoNotIndex{\@minus,\@mkboth,\@ne,\@nil,\@nomath,\@plus,\@set@topoint}
% \DoNotIndex{\@tempboxa,\@tempcnta,\@tempdima,\@tempdimb}
% \DoNotIndex{\@tempswafalse,\@tempswatrue,\@viipt,\@viiipt,\@vipt}
% \DoNotIndex{\@vpt,\@warning,\@xiipt,\@xipt,\@xivpt,\@xpt,\@xviipt}
% \DoNotIndex{\@xxpt,\@xxvpt,\\,\ ,\addpenalty,\addtolength,\addvspace}
% \DoNotIndex{\advance,\Alph,\alph}
% \DoNotIndex{\arabic,\ast,\begin,\begingroup,\bfseries,\bgroup,\box}
% \DoNotIndex{\bullet}
% \DoNotIndex{\cdot,\cite,\CodelineIndex,\cr,\day,\DeclareOption}
% \DoNotIndex{\def,\DisableCrossrefs,\divide,\DocInput,\documentclass}
% \DoNotIndex{\DoNotIndex,\egroup,\ifdim,\else,\fi,\em,\endtrivlist}
% \DoNotIndex{\EnableCrossrefs,\end,\end@dblfloat,\end@float,\endgroup}
% \DoNotIndex{\endlist,\everycr,\everypar,\ExecuteOptions,\expandafter}
% \DoNotIndex{\fbox}
% \DoNotIndex{\filedate,\filename,\fileversion,\fontsize,\framebox,\gdef}
% \DoNotIndex{\global,\halign,\hangindent,\hbox,\hfil,\hfill,\hrule}
% \DoNotIndex{\hsize,\hskip,\hspace,\hss,\if@tempswa,\ifcase,\or,\fi,\fi}
% \DoNotIndex{\ifhmode,\ifvmode,\ifnum,\iftrue,\ifx,\fi,\fi,\fi,\fi,\fi}
% \DoNotIndex{\input}
% \DoNotIndex{\jobname,\kern,\leavevmode,\let,\leftmark}
% \DoNotIndex{\list,\llap,\long,\m@ne,\m@th,\mark,\markboth,\markright}
% \DoNotIndex{\month,\newcommand,\newcounter,\newenvironment}
% \DoNotIndex{\NeedsTeXFormat,\newdimen}
% \DoNotIndex{\newlength,\newpage,\nobreak,\noindent,\null,\number}
% \DoNotIndex{\numberline,\OldMakeindex,\OnlyDescription,\p@}
% \DoNotIndex{\pagestyle,\par,\paragraph,\paragraphmark,\parfillskip}
% \DoNotIndex{\penalty,\PrintChanges,\PrintIndex,\ProcessOptions}
% \DoNotIndex{\protect,\ProvidesClass,\raggedbottom,\raggedright}
% \DoNotIndex{\refstepcounter,\relax,\renewcommand,\reset@font}
% \DoNotIndex{\rightmargin,\rightmark,\rightskip,\rlap,\rmfamily,\roman}
% \DoNotIndex{\roman,\secdef,\selectfont,\setbox,\setcounter,\setlength}
% \DoNotIndex{\settowidth,\sfcode,\skip,\sloppy,\slshape,\space}
% \DoNotIndex{\symbol,\the,\trivlist,\typeout,\tw@,\undefined,\uppercase}
% \DoNotIndex{\usecounter,\usefont,\usepackage,\vfil,\vfill,\viiipt}
% \DoNotIndex{\viipt,\vipt,\vskip,\vspace}
% \DoNotIndex{\wd,\xiipt,\year,\z@}
%
% \changes{v1.0}{1996/05/09}{First public release}
% \changes{v1.1}{1999/10/30}{Improved documentation using docmfp package}
% \changes{v1.1}{1999/10/30}{Reordered descriptions and code}
% \changes{v1.1}{1999/10/30}{Deleted Express Book examples}
% \changes{v1.1}{1999/10/30}{Updated references}
% \changes{v1.2}{1999/11/15}{Reincluded Express Book examples, plus NIAM and S-M}
% \changes{v1.3}{2000/05/22}{Added smoothing, drawdrum, and others}
% \changes{v1.4}{2000/07/10}{Added sharp and smooth lines}
% \changes{v1.5}{2003/07/31}{Minor bug fixes}
% \changes{v1.6}{2004/02/29}{More boxes}
% \changes{v1.61}{2004/03/17}{Minor namespace feature fix}
%
% \newcommand{\dtxfilename}{\texttt{expressg.dtx}}
% ^^A \def\fileversion{v1.0}
% \def\firstfiledate{1996/05/09}
% ^^A \def\fileversion{v1.1}
% ^^A \def\filedate{1999/10/30}
% ^^A \def\fileversion{v1.2}
% ^^A \def\filedate{1999/11/15}
% ^^A \def\fileversion{v1.3}
% ^^A \def\filedate{2000/05/22}
% \def\fileversion{v1.4} \def\filedate{2000/07/10}
% \def\fileversion{v1.5} \def\filedate{2003/07/31}
% \def\fileversion{v1.6} \def\filedate{2004/02/29}
% \def\fileversion{v1.61} \def\filedate{2004/03/17}
% \newcommand*{\Lpack}[1]{\textsf {#1}}           ^^A typeset a package
% \newcommand*{\Lopt}[1]{\textsf {#1}}            ^^A typeset an option
% \newcommand*{\file}[1]{\texttt {#1}}            ^^A typeset a file
% \newcommand*{\Lcount}[1]{\textsl {\small#1}}    ^^A typeset a counter
% \newcommand*{\pstyle}[1]{\textsl {#1}}          ^^A typeset a pagestyle
% \newcommand*{\Lenv}[1]{\texttt {#1}}            ^^A typeset an environment
% \newcommand*{\Express}{\textsc{express}}
% \newcommand*{\ExpressG}{\textsc{express-g}}
% \newcommand*{\Mpost}{\textsc{MetaPost}}
% \newcommand*{\Mfont}{METAFONT}
% \newcommand*{\fref}[1]{Figure~\ref{#1}}
% \newcommand*{\pref}[1]{page~\pageref{#1}}
% \newcommand*{\PS}{PostScript}
% \newcommand*{\EPS}{Encapsulated \PS}
% \newcommand*{\pdflatex}{pdf\LaTeX}
%
% \title{The \Lpack{Expressg} \Mpost{} package for drawing
%        box-line-annotation diagrams\thanks{This
%        file (\dtxfilename) has version number \fileversion, last revised
%        \filedate.}}
%
% \author{%
% Peter Wilson\\
% Catholic University of America \\
% Now at \texttt{peter.r.wilson@boeing.com}
% }
% \date{(First published \firstfiledate) \\ \filedate}
% \maketitle
% \begin{abstract}
%    The \Lpack{expressg} \Mpost{} package provides facilities to assist in
% drawing diagrams that consist of boxes, lines, and annotations.
% Particular support is provided for creating \ExpressG{} diagrams
% \end{abstract}
% \tableofcontents
% \listoffigures
%
% \StopEventually{}
%
% \section{Introduction}
%
%    \ExpressG{} is an ISO international standard graphical information 
% modeling
% language~\cite{STEP11,EBOOK}, and is a subset of the \Express{} lexical
% object-flavoured information modeling language. Like most graphical
% modeling languages, \ExpressG{} diagrams consist of boxes, lines, and
% annotations associated with the boxes and the lines. As a colleague
% of mine once put it, these kinds of graphical languages are BLA 
% (boxes, lines, annotations) with respect to lexical languages.
%
%    \Mpost~\cite{MPOST} is a powerful lexical language for producing
% \EPS\footnote{\PS{} is a registered trademark of Adobe
% Systems Incorporated.} diagrams, and is based on the \Mfont~\cite{MFONT} 
% language for creating fonts.
%
%    The \Lpack{expressg} package provides extensions to the base
% \Mpost{} language to facilitate the creation of \ExpressG{} diagrams.
% The package may also be used as is, or certainly by
% extension, for the creation of other BLA diagrams. 
%
%    \Mpost{} is typically used to generate pictures for inclusion
% in \LaTeX{} documents~\cite{LATEX}. By default it uses \TeX{} for
% typesetting any text; this behaviour can be modified so that \LaTeX{}
% is used instead. If standard \PS{} fonts (like Times) are
% used, then \LaTeX{} typesetting may be avoided altogether. Running
% \Mpost{} and methods of including \Mpost{} diagrams in (pdf)LaTeX
% documents are described in~\cite{METAFP}.
%
%
%    The \Lpack{expressg} package has been some years 
% in the making. For
% occasional diagrams I got by with using either the simple \LaTeX{}
% picture commands, 
% or general GUI drawing packages. As time went on and the number
% and complexity of the diagrams increased it became, to me at least, more
% important to use a robust and powerful drawing language than fancy
% GUI packages. This was especially important if a diagram had to be
% changed at a later date, as the language denoted exactly how the drawing
% had been produced. With the GUI tools all that you had was the picture
% and whatever graphics file format the tool used --- there was no 
% user-sensible record
% of how any result was achieved. Also, generally speaking I find it quicker
% to use \Mpost{} than a GUI tool as too much time has to be spent using
% a mouse or a cursor to reposition and rescale the drawing elements.
% 
%    Section~\ref{sec:usc} describes the facilities provided by the package.
% Several worked 
% example diagrams are presented in Section~\ref{sec:example}, together
% with information on how to run \Mpost.
% Commented code for the package macros\footnote{If requested, 
% I may be prepared to consider providing additional macros, but no promises.}
% is in Section~\ref{sec:mf}.
%
%    It is assumed that the reader has some understanding of \Mpost, although
% the example in Section~\ref{sec:example} does provide an 
% \textit{aide-memoire} for most of the \Mpost{} constructs that are likely
% to be used in creating BLA diagrams. The definitive \Mpost{}
% manual is~\cite{MPOST} but both~\cite{HOENIG98} and~\cite{GOOSSENS97}
% give some interesting examples of how to use it; in fact the front cover
% of Hoenig's book is a \Mpost{} picture. 
% Similarly, some familiarity with
% BLA diagramming would be of assistance.
%
%    I suggest that on first reading it may be sensible to skim
% Section~\ref{sec:usc} first 
% and then peruse the example in Section~\ref{sec:example} more closely. 
% After this
% go back and re-read Section~\ref{sec:usc} as it then should make 
% more sense.
%
% This manual is typeset according to the conventions of the
% \LaTeX{} \textsc{docstrip} utility which enables the automatic
% extraction of the \LaTeX{} macro source files~\cite{GOOSSENS94}.
%
%
%
% \section{The \Lpack{expressg} package} \label{sec:usc}
%
% \subsection{Internal variables}
%
% The package includes several internal variables that are initialised to
% commonly appropriate values.
%    This section describes the principal internal variables. 
% Short descriptions
% of the others, which
% are likely to be used in diagrams only very occasionally, can be found
% in Section~\ref{sec:mf}.
%
%    The values of internal variables in \Mpost{} can only be changed via
% assignment. For example:
% \begin{verbatim}
% internal_variable := expression;
% \end{verbatim}
%
% \DescribeVariable{u}
% \DescribeVariable{maxx}
% \DescribeVariable{maxy}
% |u| is the value of the unit of length for a diagram; it is initialised
% to 1mm. All lengths, except for line thicknesses,
%  are defined in terms of |u|. 
% |maxx| and |maxy| are the maximum x and y coordinate values
% for a diagram. These are initialised to the maximum size for a diagram
% within an ISO standard document (i.e., |maxx:=159.5u| and |maxy:=210u|).
%
%    The next set of variables control the thickness of lines and the
% dimensions of line end styles.
%
% \DescribeVariable{normalpen}
% Lines with normal linethickness are drawn with |normalpen|.
%
% \DescribeVariable{thickpen}
% Thick lines are drawn with |thickpen|.
%
% \DescribeVariable{thinpenpen}
% Thin lines are drawn with |thinpen|.
%
% \DescribeVariable{dotspen}
% Dotted lines are drawn with |dotspen|.
%
% \DescribeVariable{dotpen}
%  |dotpen| is for drawing the black dot line end style.
%
% \DescribeVariable{dotdiam}
% |dotdiam| is the diameter of an open circle or dot line end style.
%
% \DescribeVariable{smoothrad}
% |smoothrad| is the radius of the circular arc used to round the join between
% two straight lines.
%
% \DescribeVariable{drumlid}
% |drumlid| is the ratio of the minor to major diameter of the ellipse
% forming the top of the drum box; the larger the value the more the 
% apparent viewpoint shifts to above the drum. The default value is 0.2.
%
% \begin{figure}
%   \setlength{\unitlength}{1mm}
%   \centering
%   \begin{picture}(105,40)
%     \put(0,0){\framebox(105,40){}}
%     \put(5,0){\begin{picture}(60,40)
%   ^^A    \put(0,0){\framebox(60,40){}}
%       \thicklines
%       \put(0,20){\line(1,0){10}}
%       \put(10,10){\line(2,1){20}}
%       \put(10,30){\line(2,-1){20}}
%       \put(10,10){\line(0,1){20}}
%       \thinlines
%       \put(10,5){\vector(1,0){20}} \put(10,5){\vector(-1,0){0}}
%       \put(20,3){\makebox(0,0)[t]{length}}
%       \put(35,10){\vector(0,1){20}} \put(35,10){\vector(0,-1){0}}
%       \put(40,20){\makebox(0,0)[l]{base width}}
%     \end{picture}}
%     \put(65,0){\begin{picture}(35,40)
%  ^^A     \put(0,0){\framebox(60,40){}}
%       \thicklines
%       \put(5,20){\line(1,0){30}}
%       \put(5,10){\line(2,1){20}}
%       \put(5,30){\line(2,-1){20}}
%       \thinlines
%       \put(5,5){\vector(1,0){20}} \put(5,5){\vector(-1,0){0}}
%       \put(15,3){\makebox(0,0)[t]{length}}
%       \put(0,10){\vector(0,1){20}} \put(0,10){\vector(0,-1){0}}
%     \end{picture}}
%  \end{picture}
%  \caption{Length parameters for arrowhead and fanin line end styles}\label{fig:trifan}
% \end{figure}
%
%
% \DescribeVariable{gal}
% \DescribeVariable{gab}
% An arrowhead is defined by the height of the triangle and the base of
% the triangle forming the arrowhead, as shown in \fref{fig:trifan}. 
% |gal| and |gab| are the length 
% and base width of arrows for arrowed line end styles. 
% 
% \DescribeVariable{gfl}
% \DescribeVariable{gfb}
% Like an arrowhead, a fanin is defined by the height and the base of
% the triangular fan shape, as shown in \fref{fig:trifan}. 
% |gfl| and |gfb| are the length and base
% width of fans for fanin line end styles. They are initialised to the
% default values.
%
%    The next set of variables control certain geometric aspects of
% the various \ExpressG{} boxes.
%
% \DescribeVariable{onelineh}
% |onelineh| is the minimum height of a box that encloses a single
% line of text. This is initialised to |5u|.
%
% \begin{figure}
%   \setlength{\unitlength}{1mm}
%   \centering
%   \begin{picture}(65,40)
%     \put(0,0){\framebox(65,40){}}
%     \put(5,0){\begin{picture}(60,40)
%  ^^A     \put(0,0){\framebox(60,40){}}
%       \thicklines
%       \put(0,10){\framebox(40,15){}}
%       \put(30,10){\line(0,1){15}}
%       \thinlines
%       \put(0,5){\vector(1,0){40}} \put(0,5){\vector(-1,0){0}}
%       \put(20,3){\makebox(0,0)[t]{length}}
%       \put(45,10){\vector(0,1){15}} \put(45,10){\vector(0,-1){0}}
%       \put(47,17.5){\makebox(0,0)[l]{height}}
%       \put(40,30){\vector(-1,0){10}} \put(40,30){\vector(1,0){0}}
%       \put(35,32){\makebox(0,0)[b]{inset}}
%     \end{picture}}
%  \end{picture}
%  \caption{Parameters for (inset) boxes}\label{fig:bool}
% \end{figure}
%
% \DescribeVariable{sdtbl}
% \DescribeVariable{sdtbh}
% \DescribeVariable{sdtbs}
% The length (|sdtbl|), height (|sdtbh|) and line inset (|sdtbs|) for 
% simple data type boxes (e.g., a BOOLEAN data type box), as illustrated
% in \fref{fig:bool}. These are
% initialised as |22u|, |onelineh| and |2u| respectively.
% 
% \DescribeVariable{sdtebl}
% \DescribeVariable{sdtebh}
% \DescribeVariable{sdtebs}
% The length (|sdtebl|), height (|sdtebh|) and line inset (|sdtebs|) 
% for a simple data type EXPRESSION box. The value of |sdtebl| is |28u|,
% and the other values are the same as for the other simple data type boxes.
%
% \DescribeVariable{sdtbgel}
% \DescribeVariable{sdtbgeh}
% \DescribeVariable{sdtbges}
% The length (|sdtbgel|), height (|sdtbgeh|) and inset for GENERICENT
% data type boxes. The value of |sdtbgel| is |38u|,
% and the other values are the same as for the other simple data type boxes.
%
% \DescribeVariable{pconl}
% \DescribeVariable{pconh}
% The length (|pconl|) of an average numeric (proxy) page connector 
% (e.g., for |(9,9 (9,9))|) 
% and the height (|pconh|)  
% of an average page connector, which is initialised for one line of text.
%
% \DescribeVariable{enth}
% \DescribeVariable{typeh}
% \DescribeVariable{schemah}
% The heights of an average entity (|enth|), 
% type --- including enumeration and select --- (|typeh|),
% and schema (|schemah|) boxes. These are all initialised to cater for
% one line of text.
%
% \DescribeVariable{ish}
% \DescribeVariable{isrh}
% |ish| is the height of an interschema reference box with one line of text.
% |isrh| is the height of an interschema reference box with a rename, where
% there is one line of text each for the original and renamed
% names.
%
% \DescribeVariable{eventh}
% \DescribeVariable{eventslope}
% The height (|eventh|) of a one-lined event box, and the slope (|eventslope|)
% of the sides of an
% event box (e.g., 0.25 or 1/4).
%
%    The next set of variables control the amount of space surrounding text
% on \ExpressG{} diagrams.
%
% \DescribeVariable{nextra}
% |nextra| is the margin around names when put into entity, schema, 
% interschema reference,
% page connector, and event boxes.
% 
% \DescribeVariable{niextra}
% |niextra| is the margin around names when put into type boxes.
% 
% \DescribeVariable{ndextra}
% |ndextra| is the margin around names when used on attribute lines.
%
% \subsection{Routines}
%
% The principal aspects of an \ExpressG{} diagram are lines and line ends of 
% various styles, and boxes of several different kinds. Many routines
% are provided for positioning and drawing these on a diagram.
%
%    The following sections describe most of the routines. Short descriptions
% of the others, which
% are effectively only used as internal support routines, can be found
% in Section~\ref{sec:mf}.
%
%     A note on naming conventions used in describing the routines:
% \begin{itemize}
% \item As usual with \Mpost, a name starting with |z| is a point, and
% names staring with |x| or |y| are x- and y-coordinates respectively.
% \item The letters |i| through |n| denote (point, coordinate) suffixes.
%       Suffixes are usually a number, such as |37|, but may also have 
%       alphanumeric characters after the number (e.g., |37C2D|).
% \end{itemize}
%
%
% \subsubsection{Utility routines}
%
% Several utility routines are provided defining some shortcuts and 
% to ease some of the calculations
% that may be required when producing a diagram.
%
% \DescribeRoutine{VH}
% |VH(j, k)| calculates the intersection point, |zjvh|, between the vertical
% line through the point |zj| and the horizontal line through the point |zk|,
% as shown in \fref{fig:vhvh}.
%
%     
% \DescribeRoutine{VhV}
% |VhV(j, k)| calculates the point |zjvhv| on the vertical line through
% the point |zj| and the point |zkvhv| on the vertical line through the
% point |zk|, such that the line |zjvhv--zkvhv| is horizontal and centered
% vertically between the two given points,
% as shown in \fref{fig:vhvh}.
%
% \begin{figure}
%   \setlength{\unitlength}{1mm}
%   \centering
%   \begin{picture}(130,50)
%     \put(0,0){\framebox(120,50){}}
%     \put(5,5){\begin{picture}(30,40)
%   ^^A    \put(0,0){\framebox(30,40){}}
%       \put(5,35){\circle*{2}}
%       \put(3,37){\makebox(0,0)[br]{\texttt{zj}}}
%       \put(25,5){\circle*{2}}
%       \put(27,3){\makebox(0,0)[tl]{\texttt{zk}}}
%       \put(5,5){\circle{2}}
%       \put(3,3){\makebox(0,0)[tr]{\texttt{zjvh}}}
%       \put(5,0){\line(0,1){40}}
%       \put(0,5){\line(1,0){30}}
%     \end{picture}}
%     \put(45,5){\begin{picture}(30,40)
%   ^^A    \put(0,0){\framebox(30,40){}}
%       \put(5,35){\circle*{2}}
%       \put(3,37){\makebox(0,0)[br]{\texttt{zj}}}
%       \put(25,5){\circle*{2}}
%       \put(27,3){\makebox(0,0)[tl]{\texttt{zk}}}
%       \put(5,20){\circle{2}}
%       \put(3,18){\makebox(0,0)[tr]{\texttt{zjvhv}}}
%       \put(25,20){\circle{2}}
%       \put(27,22){\makebox(0,0)[bl]{\texttt{zkvhv}}}
%       \put(5,40){\line(0,-1){25}}
%       \put(0,20){\line(1,0){30}}
%       \put(25,0){\line(0,1){25}}
%     \end{picture}}
%     \put(85,5){\begin{picture}(30,40)
%   ^^A    \put(0,0){\framebox(30,40){}}
%       \put(5,35){\circle*{2}}
%       \put(3,37){\makebox(0,0)[br]{\texttt{zj}}}
%       \put(25,5){\circle*{2}}
%       \put(27,3){\makebox(0,0)[tl]{\texttt{zk}}}
%       \put(15,35){\circle{2}}
%       \put(17,37){\makebox(0,0)[bl]{\texttt{zjhvh}}}
%       \put(15,5){\circle{2}}
%       \put(13,3){\makebox(0,0)[tr]{\texttt{zkhvh}}}
%       \put(15,0){\line(0,1){40}}
%       \put(0,35){\line(1,0){20}}
%       \put(30,5){\line(-1,0){20}}
%     \end{picture}}
%  \end{picture}
%  \caption[Results of the \texttt{VH}, \texttt{VhV} and \texttt{HvH} 
%          routines]%
%         {Results of the \texttt{VH} (left), \texttt{VhV} (middle)
%          and \texttt{HvH} (right) routines}\label{fig:vhvh}
% \end{figure}
%
% \DescribeRoutine{HvH}
% |HvH(j, k)| calculates the point |zjhvh| on the horizontal line through
% the point |zj| and the point |zkhvh| on the horizontal line through the
% point |zk|, such that the line |zjhvh--zkhvh| is vertical and centered
% horizontally between the two given points,
% as shown in \fref{fig:vhvh}.
%
% \DescribeRoutine{VyV}
% |VyV(j, i, k)| is a generalisation of the |VhV| routine. It calculates
% the point |zjvyv| which is on the vertical line through |zj| and the
% horizontal line through |yi|, and the point |zkvyv| which is on the
% vertical line through |zk| and the horizontal line through |yi|. An example
% result is shown in \fref{fig:vyxh}.
% 
% \begin{figure}
%   \setlength{\unitlength}{1mm}
%   \centering
%   \begin{picture}(90,50)
%     \put(0,0){\framebox(90,50){}}
%     \put(10,5){\begin{picture}(30,40)
%       \put(5,35){\circle*{2}}
%       \put(3,37){\makebox(0,0)[br]{\texttt{zj}}}
%       \put(25,5){\circle{2}}
%       \put(27,3){\makebox(0,0)[tl]{\texttt{zkvyv}}}
%       \put(5,5){\circle{2}}
%       \put(3,3){\makebox(0,0)[tr]{\texttt{zjvyv}}}
%       \put(25,20){\circle*{2}}
%       \put(27,22){\makebox(0,0)[bl]{\texttt{zk}}}
%       \put(5,40){\line(0,-1){40}}  ^^A V through zj
%       \put(0,5){\line(1,0){30}}    ^^A H through yi
%       \put(32,5){\makebox(0,0)[bl]{\texttt{yi}}}
%       \put(25,0){\line(0,1){25}}   ^^A V through zk
%     \end{picture}}
%     \put(50,5){\begin{picture}(30,40)
%       \put(5,35){\circle*{2}}
%       \put(3,37){\makebox(0,0)[br]{\texttt{zj}}}
%       \put(25,5){\circle{2}}
%       \put(27,3){\makebox(0,0)[tl]{\texttt{zkhxh}}}
%       \put(25,35){\circle{2}}
%       \put(27,33){\makebox(0,0)[tl]{\texttt{zjhxh}}}
%       \put(15,5){\circle*{2}}
%       \put(13,3){\makebox(0,0)[tr]{\texttt{zk}}}
%       \put(25,0){\line(0,1){40}}    ^^A V through xi
%       \put(25,42){\makebox(0,0)[b]{\texttt{xi}}}
%       \put(0,35){\line(1,0){30}}    ^^A H through zj
%       \put(30,5){\line(-1,0){20}}   ^^A H through zk
%     \end{picture}}
%  \end{picture}
%  \caption[Results of the \texttt{VyV} and \texttt{HxH} 
%           routines]%
%          {Results of the \texttt{VyV} (left) and \texttt{HxH} (right) 
%           routines}\label{fig:vyxh}
% \end{figure}
%
% \DescribeRoutine{HxH}
% |HxH(j, i, k)| is a generalisation of the |HvH| routine. It calculates
% the point |zjhxh| which is on the horizontal line through |zj| and the
% vertical line through |xi|, and the point |zkhxh| which is on the
% horizontal line through |zk| and the vertical line through |xi|. An example
% result is shown in \fref{fig:vyxh}.
% 
% \DescribeRoutine{namespace}
% |namespace(|\meta{name}|)(|\meta{margin}|)| calculates the length of
% the text string \meta{name} plus the \meta{margin} length. You may
% use it like: \\
% |c = 3/2namespace(btex name etex)(4u)|
%
%     
% \DescribeRoutine{dashes}
% |dashes| is shorthand for a dashed linestyle. Use it like: |draw ... dashes;|.
%     
% \DescribeRoutine{dots}
% |dots| is shorthand for a dotted linestyle. Use it like: |draw ... dots;|.
%     
% \DescribeRoutine{drawgrid}
% |drawgrid| draws a 16 by 21cm, 1cm spaced grid composed of thin dashed lines.
% Labels are typeset giving the distance of the lines from the bottom left
% corner of the grid in millimetres.
%
% \subsubsection{Path routines}
%
%    The package provides some general path making routines.
%
% \DescribeRoutine{sharply}
% |sharply(zi, zj, ... zn)| will generate a piecewise linear
% path consisting of the
% straight lines from point |zi| to point |zj| \ldots to point |zn|.
% It may be used like: \\
% |draw sharply(z1, z2, z3, z4);| \\
% to draw a line through the given points.
%
% \DescribeRoutine{smoothly}
% Like the |sharply| routine, |smoothly(zi, zj, ... zn)| will generate a 
% piecewise linear path consisting of the
% straight lines from point |zi| to point |zj| \ldots to point |zn|, except
% that the corners of the path at the interior points are rounded with an
% arc of radius |smoothrad|.
% It may be used like: \\
% |draw smoothly(z1, z2, z3, z4) dashes;| \\
% to draw a dashed line with rounded corners at the given points. Or if
% a dotted line is needed:
% \begin{verbatim}
% pickup dotspen;
% draw smoothly(z1, z2, z3, z4) dots;
% pickup normalpen;
% \end{verbatim}
%
% \DescribeRoutine{~}
% Like the |&| operator, the binary |~| operator concatenates two paths
% replacing the sharp join with a circular arc of radius |smoothrad|.
%
% \subsubsection{Line drawing routines}
%
%  Routines are provided for drawing a variety of lines with differing line 
% ending styles. Line styles include dotted, dashed, and continuous, and line
% thicknesses may be normal or thick. Line end styles include open circles,
% black dots, open and closed (black) arrowheads, and a fanin style.
%
% The final uppercase characters of a line drawing routine indicate the kind
% of line end style that will be used. 
% The character |O| (uppercase O, not zero) is for an \textbf{O}pen circle, 
% |D| is for a black \textbf{D}ot,
% |OA| is for an \textbf{O}pen \textbf{A}rrowhead,
% |CA| is for a \textbf{C}losed (black) \textbf{A}rrowhead,
% and |F| is for a \textbf{F}anin.
%
%    The line ending drawing routines are described first.
% \DescribeRoutine{drawO}
% |drawO(i, j)| draws an open circle, diameter |dotdiam|, at the |zj| end
% of the vector from |zi| to |zj|.
%
% \DescribeRoutine{drawD}
% |drawD(i, j)| draws a black dot, diameter |dotdiam|, at the |zj| end
% of the vector from |zi| to |zj|.
%
% \DescribeRoutine{drawOA}
% |drawOA(i, j)| draws an open arrowhead, length |gal| and base width
% |gab|, at the |zj| end
% of the vector from |zi| to |zj|.
%
% \DescribeRoutine{drawCA}
% |drawCA(i, j)| draws a closed (black) arrowhead, length |gal| and base width
% |gab|, at the |zj| end
% of the vector from |zi| to |zj|.
%
% \DescribeRoutine{drawF}
% |drawF(i, j)| draws a fanin, length |gfl| and base width |gfb|, 
% at the |zj| end
% of the vector from |zi| to |zj|.
%
%    The line drawing routines are essentially prepackaged versions of
% different combinations of the path and line ending routines.
%     
% \DescribeRoutine{drawdots}
% |drawdots(i, j)| draws the dotted line |zi--zj|.
%
% \DescribeRoutine{drawdotsthree}
% |drawdotsthree(i, j, k)| draws the dotted piecewise linear line |zi--zj--zk|.
%
% \DescribeRoutine{drawdotsfour}
% |drawdotsfour(i, j, k, l)| draws the dotted piecewise linear line |zi--zj--zk--zl|.
%
% \DescribeRoutine{drawdotsO}
% |drawdotsO(i, j)| draws the dotted line |zi--zj|, 
% ending in an open circle, diameter |dotdiam|, at |zj|.
%
% \DescribeRoutine{drawdotsthreeO}
% |drawdotsthreeO(i, j, k)| draws the dotted piecewise linear line |zi--zj--zk|.
% ending in an open circle, diameter |dotdiam|, at |zk|.
%
% \DescribeRoutine{drawdotsfourO}
% |drawdotsfourO(i, j, k, l)| draws the dotted piecewise linear line |zi--zj--zk--zl|,
% ending in an open circle, diameter |dotdiam|, at |zl|.
%
% \DescribeRoutine{drawdotsOO}
% |drawdotsOO(i, j)| draws the dotted line |zi--zj|, 
% ending in open circles, diameter |dotdiam|, at |zi| and |zj|.
%
% \DescribeRoutine{drawdash}
% |drawdash(i, j)| draws the dashed line |zi--zj|.
%
% \DescribeRoutine{drawdashthree}
% |drawdashthree(i, j, k)| draws the dashed piecewise linear line |zi--zj--zk|.
%
% \DescribeRoutine{drawdashfour}
% |drawdashfour(i, j, k, l)| draws the dashed piecewise linear line |zi--zj--zk--zl|.
%
% \DescribeRoutine{drawdashO}
% |drawdashO(i, j)| draws the dashed line |zi--zj|,
% ending in an open circle, diameter |dotdiam|, at |zj|.
%
% \DescribeRoutine{drawdashthreeO}
% |drawdashthreeO(i, j, k)| draws the dashed piecewise linear line |zi--zj--zk|.
% ending in an open circle, diameter |dotdiam|, at |zk|.
%
% \DescribeRoutine{drawdashfourO}
% |drawdashfourO(i, j, k, l)| draws the dashed piecewise linear line |zi--zj--zk--zl|.
% ending in an open circle, diameter |dotdiam|, at |zl|.
%
% \DescribeRoutine{drawdashOO}
% |drawdashOO(i, j)| draws the dashed line |zi--zj--zk--zl|.
% ending in open circles, diameter |dotdiam|, at |zi| and |zj|.
%
% \DescribeRoutine{drawnormal}
% |drawnormal(i, j)| draws the normal thickness line |zi--zj|.
%
% \DescribeRoutine{drawnormalthree}
% |drawnormalthree(i, j, k)| draws the normal thickness piecewise linear 
% line |zi--zj--zk|.
%
% \DescribeRoutine{drawnormalfour}
% |drawnormalfour(i, j, k, l)| draws the normal thickness piecewise linear 
% line |zi--zj--zk--zl|.
%
% \DescribeRoutine{drawnormalO}
% |drawnormalO(i, j)| draws the normal thickness line |zi--zj|,
% ending in an open circle, diameter |dotdiam|, at |zj|.
%
% \DescribeRoutine{drawnormalthreeO}
% |drawnormalthreeO(i, j, k)| draws the normal thickness piecewise linear 
% line |zi--zj--zk|,
% ending in an open circle, diameter |dotdiam|, at |zk|.
%
% \DescribeRoutine{drawnormalfourO}
% |drawnormalfourO(i, j, k, l)| draws the normal thickness piecewise linear 
% line |zi--zj--zk--zl|,
% ending in an open circle, diameter |dotdiam|, at |zl|.
%
% \DescribeRoutine{drawnormalOO}
% |drawnormalOO(i, j)| draws the normal thickness line |zi--zj|,
% ending in open circles, diameter |dotdiam|, at |zi| and |zj|.
%
% \DescribeRoutine{drawnormalD}
% |drawnormalD(i, j)| draws the normal thickness line |zi--zj|,
% ending in a black dot, diameter |dotdiam|, at |zj|.
%
% \DescribeRoutine{drawnormalthreeD}
% |drawnormalthreeD(i, j, k)| draws the normal thickness piecewise linear 
% line |zi--zj--zk|,
% ending in a black dot, diameter |dotdiam|, at |zk|.
%
% \DescribeRoutine{drawnormalfourD}
% |drawnormalfourD(i, j, k, l)| draws the normal thickness piecewise linear 
% line |zi--zj--zk--zl|,
% ending in a black dot, diameter |dotdiam|, at |zl|.
%
% \DescribeRoutine{drawnormalDD}
% |drawnormalDD(i, j)| draws the normal thickness line |zi--zj|,
% ending in black dots, diameter |dotdiam|, at |zi| and |zj|.
%
% \DescribeRoutine{drawnormalCA}
% |drawnormalCA(i, j)| draws the normal thickness line |zi--zj|,
% ending in a closed (black) arrowhead, length |gal| and base width |gab|, 
% at |zj|.
%
% \DescribeRoutine{drawnormalthreeCA}
% |drawnormalthreeCA(i, j, k)| draws the normal thickness piecewise linear
% line |zi--zj--zk|
% ending in a closed (black) arrowhead, length |gal| and base width |gab|, 
% at |zk|.
%
% \DescribeRoutine{drawnormalfourCA}
% |drawnormalfourCA(i, j, k, l)| draws the normal thickness piecewise linear
% line |zi--zj--zk--zl|
% ending in a closed (black) arrowhead, length |gal| and base width |gab|, 
% at |zl|.
%
% \DescribeRoutine{drawnormalOA}
% |drawnormalOA(i, j)| draws the normal thickness line |zi--zj|,
% ending in an open arrowhead, length |gal| and base width |gab|, 
% at |zj|.
%
% \DescribeRoutine{drawnormalF}
% |drawnormalF(i, j)| draws the normal thickness line |zi--zj|,
% ending in a fanin, length |gfl| and base width |gfb|, 
% at |zj|.
%
% \DescribeRoutine{drawnormalFO}
% |drawnormalFO(i, j)| draws the normal thickness line |zi--zj|,
% ending in a fanin, length |gfl| and base width |gfb|, 
% at |zi| and an open circle, diameter |dotdiam|, at |zj|.
%
% \DescribeRoutine{drawthick}
% |drawthick(i, j)| draws the thick line |zi--zj|.
%
% \DescribeRoutine{drawthickO}
% |drawthickO(i, j)| draws the thick line |zi--zj|,
% ending in an open circle, diameter |dotdiam|, at |zj|.
%
% \DescribeRoutine{drawthickOO}
% |drawthickOO(i, j)| draws the thick line |zi--zj|,
% ending in open circles, diameter |dotdiam|, at |zi| and |zj|.
%
% \DescribeRoutine{smooth}
% |smooth(i, j, k)| replaces the sharp corner on the line |zi--zj--zk|
% with an arc radius |smoothrad|.
%
% \DescribeRoutine{smoothtwo}
% |smoothtwo(i, j, k, l)| replaces the sharp corners on the line |zi--zj--zk--zl|
% with arcs radius |smoothrad|.
%
% \DescribeRoutine{smoothdash}
% |smoothdash(i, j, k)| replaces the sharp corner on the dashed line |zi--zj--zk|
% with an arc radius |smoothrad|.
%
% \DescribeRoutine{smoothdots}
% |smoothdots(i, j, k)| replaces the sharp corner on the dotted line |zi--zj--zk|
% with an arc radius |smoothrad|.
%
%
%
% \subsubsection{Box drawing routines}
%
%    Routines are provided for drawing the different kinds of \ExpressG{} 
% boxes.
%
%    The first argument to the box drawing routines is the suffix of the
% point that will be the left-hand bottom corner point of the box. The
% last argument, except where noted below, is the text that is to be placed
% at the center of the box. Intermediate arguments, if any, are the length
% and height of the box.
%
%  Every box routine calculates the four corner points of the box and the 
% midpoints of each side of the box. For example, if the suffix is |j|,
% then as illustrated in figure~\ref{fig:boxpoints}, the corner points
% will be called |zjbl|, |zjbr|, |zjtr| and |zjtl| and the midpoints
% will be called |zjbm|, |zjmr|, |zjtm| and |zjml|. The center point for
% postioning the text is |zjc| and the center of the text is placed at
% this point. 
%
%    The text center point is not necessarily the geometric center of the box.
% The geometric center is not calculated but lies at the intersection of
% the lines |zjml--zjmr| and |zjbm--zjtm|.
%
% \begin{figure}
% \centering
% \setlength{\unitlength}{1mm}
% \begin{picture}(50,40)
%   \put(0,0){\framebox(50,40){}}
%   \put(10,10){\begin{picture}(30,20)
%     \put(0,0){\framebox(30,20){}}
%     \multiput(0,0)(15,0){3}{\circle*{2}}
%     \multiput(0,10)(15,0){3}{\circle*{2}}
%     \multiput(0,20)(15,0){3}{\circle*{2}}
%     \put(-2,-2){\makebox(0,0)[tr]{\texttt{zjbl}}}
%     \put(15,-2){\makebox(0,0)[t]{\texttt{zjbm}}}
%     \put(32,-2){\makebox(0,0)[tl]{\texttt{zjbr}}}
%     \put(-2,10){\makebox(0,0)[r]{\texttt{zjml}}}
%     \put(13,10){\makebox(0,0)[r]{\texttt{zjc}}}
%     \put(32,10){\makebox(0,0)[l]{\texttt{zjmr}}}
%     \put(-2,22){\makebox(0,0)[br]{\texttt{zjtl}}}
%     \put(15,22){\makebox(0,0)[b]{\texttt{zjtm}}}
%     \put(32,22){\makebox(0,0)[bl]{\texttt{zjtr}}}
%     \end{picture}}
%  \end{picture}
%  \setlength{\unitlength}{1pt}
%  \caption[Calculated points on rectangular boxes]%
%          {Calculated points on rectangular boxes 
%           (suffix is \texttt{j} and located at \texttt{zjbl=zj})}
%  \label{fig:boxpoints}
% \end{figure}
%     
% \DescribeRoutine{drawSCHEMA}
% A SCHEMA box is rectangular with a normal perimeter and the box is divided
% into top and bottom halves by a horizontal line.
%
% |drawSCHEMA(j, len, ht)(btex schema\_a etex)| draws a SCHEMA double rectangular 
% box of length |len| and height |ht| with its left-hand bottom corner
% at |zj|. The string |schema_a| is placed at the text center of the box,
% which is central within the upper half.
%
% \DescribeRoutine{drawBINARY}
% A simple data type box is rectangular with a solid boundary and a solid
% interior vertical line near the right hand edge.
%
% |drawBINARY(j)| draws a simple data type rectangular 
% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
% at |zj|. The string |BINARY| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawBOOLEAN}
% |drawBOOLEAN(j)| draws a simple data type rectangular 
% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
% at |zj|. The string |BOOLEAN| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawCOMPLEX}
% |drawCOMPLEX(j)| draws a simple data type rectangular 
% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
% at |zj|. The string |COMPLEX| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawEXPRESSION}
% |drawEXPRESSION(j)| draws a simple data type rectangular 
% box of length |sdtbel| and height |sdtbeh| with its left-hand bottom corner
% at |zj|. The string |EXPRESSION| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawGENERIC}
% |drawGENERIC(j)| draws a simple data type rectangular 
% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
% at |zj|. The string |GENERIC| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawINTEGER}
% |drawINTEGER(j)| draws a simple data type rectangular 
% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
% at |zj|. The string |INTEGER| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawLOGICAL}
% |drawLOGICAL(j)| draws a simple data type rectangular 
% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
% at |zj|. The string |LOGICAL| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawNUMBER}
% |drawNUMBER(j)| draws a simple data type rectangular 
% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
% at |zj|. The string |NUMBER| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawREAL}
% |drawREAL(j)| draws a simple data type rectangular 
% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
% at |zj|. The string |REAL| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawSTRING}
% |drawSTRING(j)| draws a simple data type rectangular 
% box of length |sdtbl| and height |sdtbh| with its left-hand bottom corner
% at |zj|. The string |STRING| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawENUM}
% An ENUMERATION box is a rectangular box with a dashed perimeter and an 
% interior dashed vertical line near the right hand edge.
%
% |drawENUM(j, len, ht)(btex an\_enum etex)| draws a rectangular dashed ENUMERATION type
% box of length |len| and height |ht| with its left-hand bottom corner
% at |zj|. The string |an_enum| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawSELECT}
% A SELECT box is rectangular with a dashed boundary and an interior
% dashed vertical
% line near the left hand edge.
%
% |drawSELECT(j, len, ht)(btex a\_select etex)| draws a rectangular dashed SELECT type
% box of length |len| and height |ht| with its left-hand bottom corner
% at |zj|. The string |a_select| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawTYPE}
% A TYPE box is rectangular with a dashed boundary.
%
% |drawTYPE(j, len, ht)(btex a\_type etex)| draws a rectangular dashed TYPE type
% box of length |len| and height |ht| with its left-hand bottom corner
% at |zj|. The string |a_type| is placed at the text center of the box,
% which is central within the main part of the box.
%
% \DescribeRoutine{drawENT}
% An ENTITY box is a rectangular box with a solid boundary.
%
% |drawENT(j, len, ht)(btex an\_entity etex)| draws a rectangular ENTITY type
% box of length |len| and height |ht| with its left-hand bottom corner
% at |zj|. The string |an_entity| is placed at the text center of the box,
% which is also the geometric center of the box.
%
% \DescribeRoutine{drawPREF}
% A page reference box is a rectangle with rounded ends and a solid boundary.
%
% |drawPREF(j, len, ht)(btex page ref etex)| draws an oval page
% reference 
% box of length |len| and height |ht| with its left-hand bottom corner
% at |zj|. The string |page ref| is placed at the text center of the box,
% which is also the geometric center of the box.
%
% \DescribeRoutine{drawISU}
% An interschema box is a rectangle surrounding a page reference like box.
% The rectangular box may have either a solid or a dashed boundary.
%
% |drawISU(j, len, ht)(btex sch.ent etex)| draws a three-part rectangular
% interschema USE 
% box of length |len| and height |ht| with its left-hand bottom corner
% at |zj|. The string |sch.ent| is placed at the text center of the box,
% which is also the geometric center of the box.
%
% \DescribeRoutine{drawISUR}
% |drawISUR(j, len, ht)(btex sch.ent etex)(btex newname etex)| draws a three-part rectangular
% interschema USE and RENAME
% box of length |len| and height |ht| with its left-hand bottom corner
% at |zj|. The string |sch.ent| is placed at the text center of the box,
% which is also the geometric center of the box. The string |newname| is
% placed at the geometric center of the bottom third of the box (this is
% the point |zjrnm|).
%
% \DescribeRoutine{drawISR}
% |drawISR(j, len, ht)(btex sch.ent etex)| draws a three-part rectangular
% dashed interschema REFERENCE 
% box of length |len| and height |ht| with its left-hand bottom corner
% at |zj|. The string |sch.ent| is placed at the text center of the box,
% which is also the geometric center of the box.
%
% \DescribeRoutine{drawISRR}
% |drawISRR(j, len, ht)(btex sch.ent etex)(btex newname etex)| draws a three-part rectangular
% dashed interschema REFERENCE and RENAME
% box of length |len| and height |ht| with its left-hand bottom corner
% at |zj|. The string |sch.ent| is placed at the text center of the box,
% which is also the geometric center of the box. The string |newname| is
% placed at the geometric center of the bottom third of the box (this is
% the point |zjrnm|).
%
% \DescribeRoutine{drawLEVENT}
% An EVENT box is a rhomboid with a solid boundary.
%
% |drawLEVENT(j, len, ht)(btex local\_event etex)| draws a rhomboidal
% Local EVENT 
% box of length |len|, height |ht| and slope |eventslope|  with its left-hand bottom corner
% at |zj|. The string |local_event| is placed at the text center of the box,
% which is also the geometric center of the box. Like the rectangular boxes,
% the calculated bottom and top middle points are vertically below and above
% the geometric center, but this means that they are \emph{not} midway
% beteen the bottom and top corner points. This is illustrated in
% \fref{fig:eventpoints}.
%
% \begin{figure}
% \centering
% \setlength{\unitlength}{1mm}
% \begin{picture}(55,40)
%   \put(0,0){\framebox(55,40){}}
%   \put(10,10){\begin{picture}(40,20)
% ^^A    \put(0,0){\framebox(30,20){}}
%     \put(0,0){\line(1,0){30}}
%     \put(5,20){\line(1,0){30}}
%     \put(0,0){\line(1,4){5}}
%     \put(30,0){\line(1,4){5}}
%     \multiput(0,0)(30,0){2}{\circle*{2}}
%     \multiput(2.5,10)(30,0){2}{\circle*{2}}
%     \multiput(5,20)(30,0){2}{\circle*{2}}
%     \multiput(17.5,0)(0,10){3}{\circle*{2}}
%     \put(-2,-2){\makebox(0,0)[tr]{\texttt{zjbl}}}
%     \put(17.5,-2){\makebox(0,0)[t]{\texttt{zjbm}}}
%     \put(32,-2){\makebox(0,0)[tl]{\texttt{zjbr}}}
%     \put(0.5,10){\makebox(0,0)[r]{\texttt{zjml}}}
%     \put(15.5,10){\makebox(0,0)[r]{\texttt{zjc}}}
%     \put(34.5,10){\makebox(0,0)[l]{\texttt{zjmr}}}
%     \put(3,22){\makebox(0,0)[br]{\texttt{zjtl}}}
%     \put(17.5,22){\makebox(0,0)[b]{\texttt{zjtm}}}
%     \put(37,22){\makebox(0,0)[bl]{\texttt{zjtr}}}
%     \end{picture}}
%  \end{picture}
%  \setlength{\unitlength}{1pt}
%  \caption[Calculated points on rhomboidal boxes]%
%          {Calculated points on rhomboidal boxes 
%           (suffix is \texttt{j} and located at \texttt{zjbl=zj})}
%  \label{fig:eventpoints}
% \end{figure}
%     
% \DescribeRoutine{drawGEVENT}
% |drawGEVENT(j, len, ht)(btex global\_event etex)| draws a thick rhomboidal 
% Global EVENT 
% box of length |len|, height |ht| and slope |eventslope| with its left-hand bottom corner
% at |zj|. The string |global_event| is placed at the text center of the box,
% which is also the geometric center of the box.
%
%     
% \DescribeRoutine{drawcirclebox}
% A circle box is a circle with a solid boundary.
%
% |drawcirclebox(j, diam)(btex ABC etex)| draws a circle diameter |diam|
% and center at |zj|. The string |ABC| is placed at the center of the circle.
% In this case the four midside points,  |zjbm|, |zjmr|, |zjtm| and |zjml|,
% are at on the circle at the extreme bottom, right, top and left (i.e., at
% the S, E, N and W compass points). The
% corner points, |zjbl|, |zjbr|, |zjtr| and |zjtl|, are also on the 
% circumference midway between the midpoints (i.e., at the SW, SE, NE and NW
% compass points).
%
% \DescribeRoutine{drawdashcircle}
% |drawdashcircle(j, diam)| draws a dashed circle. The location
% and size parameters are the same as for |drawcirclebox|, as are the
% calculated points.
%
% \subsection{Extra BLA variables and routines}
%
%    In addition to the facilities described above for \ExpressG{}
% diagrams, extra line styles and boxes are provided for other
% kinds of diagrams.
%
%    Additional line end styles are coded by: 
% |A| for an \textbf{A}rrowhead,
% |OD| for an \textbf{O}pen \textbf{D}iamond,
% |CD| for a \textbf{C}losed \textbf{D}iamond.
%
% \DescribeVariable{gdl}
% \DescribeVariable{gdb}
% The variables |gdl| and |gdb| hold the the length and base width of
% diamond line end styles (see \fref{fig:diales}), 
% analagous to the corresponding variables
% for arrow heads and fanin. By default, |gdl| is twice the default
% arrowhead length and |gdb| is three quarters of the default
% arrowhead base width.
%
% \begin{figure}
%   \setlength{\unitlength}{1mm}
%   \centering
%   \begin{picture}(90,40)
%     \put(0,0){\framebox(90,40){}}
%     \put(5,0){\begin{picture}(85,40)
%   ^^A    \put(0,0){\framebox(85,40){}}
%       \thicklines
%       \put(0,20){\line(1,0){10}}
%  ^^A     \put(10,10){\line(2,1){20}}
%  ^^A     \put(10,30){\line(2,-1){20}}
%  ^^A     \put(10,10){\line(0,1){20}}
%       \put(10,20){\line(2,1){20}}
%       \put(10,20){\line(2,-1){20}}
%       \put(50,20){\line(-2,1){20}}
%       \put(50,20){\line(-2,-1){20}}
%       \thinlines
%  ^^A     \put(10,5){\vector(1,0){20}} \put(10,5){\vector(-1,0){0}}
%  ^^A     \put(20,3){\makebox(0,0)[t]{length}}
%  ^^A     \put(35,10){\vector(0,1){20}} \put(35,10){\vector(0,-1){0}}
%  ^^A     \put(40,20){\makebox(0,0)[l]{base width}}
%       \put(10,5){\vector(1,0){40}} \put(10,5){\vector(-1,0){0}}
%       \put(30,3){\makebox(0,0)[t]{length}}
%       \put(55,10){\vector(0,1){20}} \put(55,10){\vector(0,-1){0}}
%       \put(60,20){\makebox(0,0)[l]{base width}}
%     \end{picture}}
%  \end{picture}
%  \caption{Length parameters for diamond line end styles}\label{fig:diales}
% \end{figure}
%
% \DescribeRoutine{drawA}
% |drawA(i, j)| draws a simple arrowhead, length |gal| and base width
% |gab|, at the |zj| end
% of the vector from |zi| to |zj|.
%
%
% \DescribeRoutine{drawDCA}
% |drawDCA(i, j)| draws a double closed arrowhead, each of length |gal| 
% and base width
% |gab|, at the |zj| end
% of the vector from |zi| to |zj|.
%
%
% \DescribeRoutine{drawOD}
% |drawOD(i, j)| draws an open diamond, length |gdl| and base width
% |gdb|, at the |zj| end
% of the vector from |zi| to |zj|.
%
% \DescribeRoutine{drawCD}
% |drawCD(i, j)| draws a closed (black) diamond, length |gdl| and base width
% |gdb|, at the |zj| end
% of the vector from |zi| to |zj|.
%
%
% \DescribeRoutine{drawdashA}
% |drawdashA(i, j)| draws the dashed line |zi--zj|,
% ending in an arrowhead, length |gal| and base width |gab|, 
% at |zj|.
%
% \DescribeRoutine{drawdashOA}
% |drawdashOA(i, j)| draws the dashed line |zi--zj|,
% ending in an open arrowhead, length |gal| and base width |gab|, 
% at |zj|.
%
% \DescribeRoutine{drawnormalOD}
% |drawnormalOD(i, j)| draws the normal thickness line |zi--zj|,
% ending in an open diamond, length |gdl| and base width |gdb|, 
% at |zj|.
%
% \DescribeRoutine{drawnormalCD}
% |drawnormalCD(i, j)| draws the normal thickness line |zi--zj|,
% ending in a closed (black) diamond, length |gdl| and base width |gdb|, 
% at |zj|.
%
% \DescribeRoutine{drawcircleA}
% |drawcircleA(j, diam)| draws a circle diameter |diam| centered at |zj|.
% A counterclockwise pointing arrow is placed at the top of the circle.
% The midside and `corner' points are the same as calculated by
% the |drawcirclebox| routine.
%
% \DescribeRoutine{drawDot}
% |drawDot(j, diam)| draws a black dot, diameter |diam| centered at |zj|.
% There are no calculated points.
%
% \DescribeRoutine{drawCircledDot}
% |drawCircledDot(j, diam)| draws a black dot with a circle outside
% it, overall diameter |diam|, centered at |zj|.
% There are no calculated points. This could be used for a UML
% `bullseye'. The white ring should obscure anything 
% drawn earlier that lies underneath it (by definition the black dot covers 
% up anything underneath itself). For example: 
% \begin{verbatim}
% draw z1--z2;            % line from z1 to z2
% drawCircledDot(2, len); % obscures last len of above line
% draw z3--z2;            % not obscured
% \end{verbatim}
%
%    Commands of the form |draw...box| have a text argument
% which is printed at the center of the box. If an empty box is
% required the text argument should be an empty string (|""|). For
% example |draw...box(...)("")|.
%
% \DescribeRoutine{drawcardbox}
% |drawcardbox(j, len, ht, fold)(btex note etex)| draws a rectangular
% box, length |len| and height |ht|, with its bottom left corner at |zj|.
% The top right corner of the box is folded down, with the side length
% of the fold given by |fold|. The string |note| is placed at the
% center of the box. If no text is required, then use an empty string (i.e.,
% |""|), as in \\
% |\drawcardbox(23, el, eh, 1/8eh)("")|
%
% \DescribeRoutine{drawdiamondbox}
% |drawdiamondbox(j, len, ht)(btex str etex)| draws a diamond shaped 
% box, length |len| and height |ht|, with its center at |zj|. The usual
% corner, center and midpoints are also calculated except that the points
% |z$tm| etc., are at the corners of the diamond and the points |z$tl| etc.,
% are at the middle of each line, as shown in \fref{fig:diamondpoints}.
% The text |str| is placed at the center of the box.
%
% \begin{figure}
% \centering
% \setlength{\unitlength}{1mm}
% \begin{picture}(50,40)
%   \put(0,0){\framebox(50,40){}}
%   \put(10,10){\begin{picture}(30,20)
%  ^^A   \put(0,0){\framebox(30,20){}}
%     \put(0,10){\line(3,2){15}}
%     \put(0,10){\line(3,-2){15}}
%     \put(30,10){\line(-3,2){15}}
%     \put(30,10){\line(-3,-2){15}}
%     \multiput(0,10)(15,0){3}{\circle*{2}}
%     \multiput(15,0)(0,20){2}{\circle*{2}}
%     \multiput(7.5,5)(0,10){2}{\circle*{2}}
%     \multiput(22.5,5)(0,10){2}{\circle*{2}}
%     \put(13,10){\makebox(0,0)[r]{\texttt{zjc}}}
%     \put(15,-2){\makebox(0,0)[t]{\texttt{zjbm}}}
%     \put(-2,10){\makebox(0,0)[r]{\texttt{zjml}}}
%     \put(32,10){\makebox(0,0)[l]{\texttt{zjmr}}}
%     \put(15,22){\makebox(0,0)[b]{\texttt{zjtm}}}
%
%     \put(5.5,3){\makebox(0,0)[tr]{\texttt{zjbl}}}
%     \put(24.5,3){\makebox(0,0)[tl]{\texttt{zjbr}}}
%     \put(5.5,17){\makebox(0,0)[br]{\texttt{zjtl}}}
%     \put(24.5,17){\makebox(0,0)[bl]{\texttt{zjtr}}}
%     \end{picture}}
%  \end{picture}
%  \setlength{\unitlength}{1pt}
%  \caption[Calculated points on diamond boxes]%
%          {Calculated points on diamond boxes 
%           (suffix is \texttt{j} and located at \texttt{zjc=zj})}
%  \label{fig:diamondpoints}
% \end{figure}
%     
%
% \DescribeRoutine{drawtwodiamondbox}
% |drawtwodiamondbox(j, len, ht, inset)(btex str etex)| draws a diamond shaped 
% box, length |len| and height |ht|, with its center at |zj|. 
% The text |str| is placed at the center of the box.
% A second diamond is drawn inside the first. The parameter |inset| is
% the space between adjacent outer and inner lines.
% No calculated points are available for the inner diamond.
%
% \DescribeRoutine{drawdoublerectangle}
% |drawdoublerectangle(j, len, ht, tf)| draws a rectangular box, length |len|
% and height |ht|, located with its bottom left corner at |zj|. The box
% is divided horizontally
% into a top and bottom portion, with the height of the top portion being
% the fraction |tf| of the total height of the box. The center points of
% the two portions are calculated as |zjct| and |zjcb| for the top and
% bottom respectively. 
% The ends of the dividing line are at |zjtfl| and |zjtfr|.
%
% \DescribeRoutine{drawtriplerectangle}
% |drawtriplerectangle(j, len, ht, tf, bf)| draws a rectangular box, length |len|
% and height |ht|, located with its bottom left corner at |zj|. The box
% is divided horizontally
% into a top, middle and bottom portion.
% The height of the top portion is the fraction |tf| of the total height 
% of the box. 
% The height of the bottom portion is the fraction |bf| of the total height 
% of the box. 
% The center points of
% the three portions are calculated as |zjct|, |zjcm| and |zjcb| for the 
% top, middle and bottom respectively.
% The ends of the dividing lines are at |zjtfl| and |zjtfr| for the upper
% line, and at |zjbfl| and |zjbfr| for the lower line.
%
% \DescribeRoutine{hiderectangle}
% |hiderectangle(j, len, ht)| draws an invisible rectangular box, length |len|
% and height |ht|, located with its bottom left corner at |zj|. The box
% covers up anything underneath it. Note that unlike all the other boxes
% the only point handle to the box is the bottom left corner --- the
% |zjbl|, |zjtr|, etc.,  points are not available and hence cannot
% be used for positioning or alignment purposes.
%
% \DescribeRoutine{drawdashboxover}
% |drawdashboxover(j, len, ht)| draws a dashed rectangular box, length |len|
% and height |ht|, located with its bottom left corner at |zj|. The box
% covers up anything underneath it.
%
% \DescribeRoutine{drawindexbox}
% |drawindexbox(j, len, ht, lenp, htp)(btex str etex)| 
% draws a rectangular box, length |len|
% and height |ht|, located with its bottom left corner at |zj|. Another
% rectangular box, length |lenp| and height |htp|, is drawn with its
% bottom left corner at the top left corner of the first box (like an index
% card). The main box points are |zjbl| etc., but the secondary box
% points are |zjP.bl|, |zjP.bm| etc. The text |str| is placed at the center
% (|zjP.c|) of the secondary box.
%
% \DescribeRoutine{drawroundedbox}
% |drawroundedbox(j, len, ht, rad)(btex str etex)| 
% draws a rectangular box, length |len|
% and height |ht|, located with its bottom left corner at |zj|. The corners
% of the box are rounded using radius |rad|. If |2rad| is greater
% than |len| or |ht|, then |2rad| is reduced to the lesser of |len| and
% |ht|, thereby producing at least one pair of semicircular sides.
% The text |str| is placed at the center of the box.
%
% \DescribeRoutine{drawovalbox}
% |drawovalbox(j, len, ht)(btex str etex)|
% draws an elliptical box, 
% horizontal diameter |len|
% and vertical diameter |ht|, located with its center at |zj|. Like the 
% diamond box, |zjtm|, |zjmr|, etc., are at the extremes of the ellipse
% and the points |zjtr|, |zjbr|, etc., are on the ellipse approximately
% halfway between the extremum points, similar to the positions shown
% in \fref{fig:diamondpoints}. The text |str| is placed at the center 
% of the box.
%
% \DescribeRoutine{drawoutputbox}
% |drawoutputbox(j, len, ht)(btex str etex)|
% draws a box, 
% length |len| and height |ht|, located with its bottom left corner at |zj|. 
% The bottom of the box is a wavy line and the other three sides
% are straight. The text |str| is placed at the center of the box.
% This kind of box is often used as a flowchart symbol for output; 
% it is meant to be a represention of printed paper which has been
% torn from a long continuous roll.
%
%
% \DescribeRoutine{drawdashellipse}
% |drawdashellipse(j, len, ht)| 
% draws a dashed ellipse. The location and dimensional parameters 
% correspond to those for |drawovalbox|, as do the calculated points.
% 
% \DescribeRoutine{drawdrum}
% |drawdrum(j, len, ht)(btex str etex)|
% draws a `drum' box. This is constructed as a rectangular box of width
% width |len| and height |ht|, with its bottom left hand corner at |zj|.
% The horizontal line at the bottom of the
% rectangle is replaced by a half-ellipse with a major diameter of |len|
% and the minor diameter given by |drumlid*len|. The horizontal line
% at the top is replaced by a full ellipse with the same dimensions.
%
%\begin{figure}
%\centering
%\setlength{\unitlength}{0.6mm}
%
%\begin{picture}(100,100)
%  \put(0,0){\framebox(120,120){}}
%  \put(20,20){\begin{picture}(80,80)
%    \put(0,10){\line(0,1){60}}
%    \put(80,10){\line(0,1){60}}
%    \qbezier(0,10)(0,0)(40,0)
%    \qbezier(40,0)(80,0)(80,10)
%
%    \qbezier(0,70)(0,80)(40,80)
%    \qbezier(40,80)(80,80)(80,70)
%    \qbezier(0,70)(0,60)(40,60)
%    \qbezier(40,60)(80,60)(80,70)
%
%    \multiput(0,10)(0,30){3}{\circle*{2}}
%    \put(-2,10){\makebox(0,0)[r]{\texttt{zjbl}}}
%    \put(-2,40){\makebox(0,0)[r]{\texttt{zjml}}}
%    \put(-2,70){\makebox(0,0)[r]{\texttt{zjtl}}}
%    \multiput(80,10)(0,30){3}{\circle*{2}}
%    \put(82,10){\makebox(0,0)[l]{\texttt{zjbr}}}
%    \put(82,40){\makebox(0,0)[l]{\texttt{zjmr}}}
%    \put(82,70){\makebox(0,0)[l]{\texttt{zjtr}}}
%    \put(40,0){\circle*{2}}
%    \put(40,-2){\makebox(0,0)[t]{\texttt{zjbm}}}
%    \put(40,80){\circle*{2}}
%    \put(40,82){\makebox(0,0)[b]{\texttt{zjtm}}}
%    \put(40,35){\circle*{2}}
%    \put(40,37){\makebox(0,0)[b]{\texttt{zjc}}}
%
%    \put(20,1){\circle*{2}}
%    \put(20,-1){\makebox(0,0)[t]{\texttt{zjbml}}}
%    \put(60,1){\circle*{2}}
%    \put(60,-1){\makebox(0,0)[t]{\texttt{zjbmr}}}
%    \put(20,79){\circle*{2}}
%    \put(20,81){\makebox(0,0)[b]{\texttt{zjtml}}}
%    \put(60,79){\circle*{2}}
%    \put(60,81){\makebox(0,0)[b]{\texttt{zjtmr}}}
%    
%  \end{picture}}
%\end{picture}
%\setlength{\unitlength}{1pt}
%\caption[Calculated points on a drum]{Calculated points on a drum 
%         (suffix is \texttt{j} and located at \texttt{zjbl=zj})} 
%  \label{fig:drum}
%\end{figure}
%
% As shown in Figure~\ref{fig:drum}, 
% the calculated points on the vertical sides of the drum are the same
% as for a rectangular box. There are three calculated points on the base
% of the drum, called |zjbml|, |zjbm| and |zjbmr|. Similarly there are
% three points on the top of the drum called |zjtml|, |zjtm| and |zjtmr|.
% The center point, |zjc| is halfway between the sides and halfway between
% the two lower ellipse halves. The text |str| is placed at this center point.
%
% \DescribeRoutine{drawstickman}
% |drawstickman(j, len, ht)|
% draws a genderless full frontal (or rear) stick figure enclosed in 
% an invisible box, 
% length |len| and height |ht|, located with its bottom left corner at |zj|. 
% This can be used, for example to represent an actor in a UML Use Case
% diagram. Setting the height to be twice the length produces a reasonable
% result, for instance:
% \verb?drawstickman(3, wd, 2wd);?
%
%     
% \section{An example} \label{sec:example}
%
%    The example attempts to bring out the main methods that can be used
% in defining \ExpressG{} diagrams. The code for eleven diagrams is provided, none
% of which necessarily has anything to do with a real example of \ExpressG{}
% modeling, but rather is meant to be illustrative of diagramming techniques.
%
%    This section is best studied with a copy of the printed diagrams to
% hand. Section~\ref{sec:run} on \pref{sec:run} explains briefly how
% to run the example and obtain the diagrams.
% 
%    The default extension for a \Mpost{} file is \file{.mp}.
%    \begin{macrocode}
%<*eg>
%%% EXPEG.MP  Example MetaPost EXPRESS-G diagrams

%    \end{macrocode}
%
%    Assuming that the diagrams are to be eventually embedded in, or processed
% through, a \LaTeX{} document then any \TeX{} macros must come at the
% start of the file between a |verbatimtex| \ldots |etex| pair. When dealing
% with text, \Mpost{} does not handle more than a single line. The macro
% below is to enable two lines of text to be handled by \Mpost.
%     
%    \begin{macrocode}

% use btex \twolines{first}{second} etex for two-line labels
verbatimtex \def\twolines#1#2{\vbox{\hbox{#1} \hbox{#2}}} etex

%    \end{macrocode}
%
%    The \Lpack{expressg} package file has to be input to make the routines
% available.
%    \begin{macrocode}
input expressg

%    \end{macrocode}
%
% \subsection{Diagram 1: Some boxes and lines}
%
%   Many diagrams can be defined in one file. Each diagram starts with
% |beginfig(N)|, where N is a unique integer, and ends with |endfig;|.
% \EPS{} for each diagram is written to a file called
% \file{mproot.N}, where \file{mproot} is the root name of the input file. 
% In our
% case the output files will be \file{expeg.1} through \file{expeg.11}.
%    \begin{macrocode}
beginfig(1)

%    \end{macrocode}
%
%    The first diagram consists of some of the \Lpack{expressg} box and line styles.
% The main point is to illustrate how \Mpost{} allows the boxes to be aligned.
% Start off by defining a point |z1| at the origin. By default, a variable name
% starting with the letter |z| is assumed to be a point. Similarly, variables
% starting with |x| and |y| are assumed to be x- and y-coordinates. If |zk|
% is defined with a value then automatically |xk| is the value of the x 
% coordinate of 
% the point |zk| and |yk| is the value of the
% y coordinate. Conversely, if |xj| and |yj| are defined, |zj| is automatically
% defined.
%
%    Note that the |=| sign denotes an equation, not an assignment. The power
% of \Mpost{} comes from its ability to solve linear equations.
%
%    Having defined the point |z1|, draw an EXPRESSION box with its bottom
% left hand corner at |z1|.
%    \begin{macrocode}
z1=(0,0);
drawEXPRESSION(1);

%    \end{macrocode}
%
%    Remember that when a box is drawn, its corner and mid points are 
% calculated. These can be used in defining other points. In particular
% there is the point |z1tr| which is the top right hand corner
% of the EXPRESSION box. Also, if another box is drawn at point |z2| then
% it will have its bottom left hand corner at |z2bl|.
%
%    The point |z2bl| is defined by a linear equation with respect to
% the point |z2|. As \Mpost{} can solve linear equations, given the
% point |z2bl| it can solve for the point |z2|. 
%
%    The next box has its bottom left hand corner at the top right hand
% corner of the EXPRESSION box, by specifying that the
% point |z2bl| and |z1tr| are the same location and then drawing a box located
% at |z2|. The third (BOOLEAN) box is also stacked in the same way with 
% respect to the second (INTEGER) box.
% 
%    \begin{macrocode}
z2bl=z1tr;
drawINTEGER(2);

z3bl=z2tr;
drawBOOLEAN(3);

%    \end{macrocode}
%
%    Next a piece of circled text is drawn. Using the same method as before,
% the bottom of the circle is made to be coincident with the middle of the top
% of the BOOLEAN box. The |namespace| routine is used to specify the circle
% diameter. Note that an argument to a routine can itself be a routine.
%    \begin{macrocode}
z4bm=z3tm;
drawcirclebox(4, namespace(btex ABS etex)(nextra))(btex ABS etex);

%    \end{macrocode}
%
% \Mpost{} is a typed language, and new variables can be declared of a
% particular type. A |numeric| variable holds a number (or a length).
% The diameter of the circle just drawn is going to be used as a length
% in later parts of this diagram, so it is sensible to store its value
% in a new variable called |diam|. We then use it in drawing another
% circle directly on top of the first one.
%    \begin{macrocode}
numeric diam;
diam = namespace(btex ABS etex)(nextra);

z5bm=z4tm;
drawcirclebox(5, diam)(btex SAB etex);

%    \end{macrocode}
%
% The next element in the diagram is an ENTITY box. 
% We use the default height for the entity box and the default page connector
% length as its length (no reason, but it saves inventing another variable 
% or value).
%
%    The ENTITY box is positioned with respect to the SAB circle, but in a
% slightly more complicated way than earlier positions. We want the left hand
% side of the box to align with the right hand side of the circle. Also,
% the middle of the box should align with the top of the circle. 
%
%    The ENTITY box will be located at point |z6|. The easiest way is to
% specify |z6| is |z6ml=(x5mr, y5tm)|, but to demonstrate more of \Mpost's
% equation solving abilities a more complicated approach is taken to the 
% specification of the x coordinate. The horizontal distance between the
% points |z5ml| and |z5tl| on the circle is the same as the distance
% between the points |z5tr| and |z5mr|. We can express this as
% |x5ml-x5tl = x5tr-x5mr|. As we want |x6ml|, which is the same as |x6bl|,
%  to be the same as |x5mr| we
% can substitute into this equation, as done in the code below. Note that
% \Mpost{} can solve for the unknown |x6bl| even though it is on  
% the right hand side
% of the equation because the other three values are known.
%
%     The y coordinate of the point |z6mr| is specified as
% equal to the y coordinate of the top of the circle. Because of the linear
% relations involving all the points on a box, it is sufficient to provide
% one x coordinate and one y coordinate to fix all the points on the box.
%    \begin{macrocode}
x5ml-x5tl = x5tr-x6bl;
y6mr=y5tm;
drawENT(6, pconl, enth)(btex an\_ent etex);

%    \end{macrocode}
%
%    The geometric center of the next box, an LEVENT, is vertically above
% the geometric center of the ENTITY box, and the bottom of LEVENT is slightly
% (one lenth unit) above the top of the ENTITY box. This is accomplished here
% by specifying |z7bm| in terms of expressions involving the coordinates
% of the point |z6tm|.
%    \begin{macrocode}
z7bm=(x6tm,y6tm+u);
drawLEVENT(7, pconl, eventh)(btex levent etex);

%    \end{macrocode}
%
%    At point |z8| a GEVENT box is drawn. It's bottom left hand corner is
% vertically above the top left hand corner of the LEVENT box. If you look
% at the resulting diagram, you will see that GEVENT is shifted right with
% respect to LEVENT. For vertical alignment of EVENT boxes it is best to
% use the middle rather than corner points.
%    \begin{macrocode}
z8=(x7tl, y7tr+u);
drawGEVENT(8, pconl, eventh)(btex gevent etex);

%    \end{macrocode}
%
% \DescribeRoutine{mediation}
%    For the last of the aligned boxes another aspect of \Mpost{} is used.
% \Mpost{} provides a \emph{mediation} facility whose syntax is |frac[a,b]|.
% The result of a mediation is a value that is |frac| between the value |a|
% and the value |b|. For example, the result of |0.25[10,30]| is 15. Similarly,
% the result of |1/3[zj,zk]| is the point one third of the way between point
% |zj| and point |zk|.
%
%    The SCHEMA box is positioned with its bottom right hand corner at one
% eighth of the way along, and at the top of, the BOOLEAN box.
%    \begin{macrocode}
z9br=1/8[z3tl,z3tr];
drawSCHEMA(9, pconl, schemah)(btex a\_schema etex);

%    \end{macrocode}
%
%    The second half of the diagram illustrates various line and end 
% styles. These are all horizontal, the same length and are aligned 
% vertically, so
% define the x coordinate |xmid| of the left hand end of the lines, and
% the length |len| of the lines.
%    \begin{macrocode}
numeric xmid, len;
xmid = x8tr + diam;
len = 2diam;

%    \end{macrocode}
%
% \DescribeRoutine{shifted}
%    The next line of code exhibits another \Mpost{} function. A point can
% be specified as being some other point that is \emph{shifted} by given
% amounts in the x and y directions. More precisely, the shift is specified
% by a pair of values, written as |(a,b)|. The first line is aligned
% vertically with the center of the first box and its start point is |z11|.
% The end point, |z111|, is specified as being the start point shifted 
% horizontally by the length of the line.
%    \begin{macrocode}
z11=(xmid, y1ml); z111=z11 shifted (len, 0);
drawdashO(11, 111);

%    \end{macrocode}
%
%    Because we will be using the same horizontal shift for all the lines,
% define a \emph{pair}, called |moveright|, that is the required shift.
% The next two lines are also aligned vertically with the centers of the
% second and third boxes.
%    \begin{macrocode}
pair moveright;
moveright = (len, 0);

z12=(xmid, y2ml); z121=z12 shifted moveright;
drawnormalO(12, 121);

z13=(xmid, y3ml); z131=z13 shifted moveright;
drawthickO(13, 131);

%    \end{macrocode}
%
%   The remaining lines will have the same vertical spacing as the first three,
% so define another pair, |moveup|, that we can use for vertical shift.
%    \begin{macrocode}
pair moveup;
moveup = (0, y13-y12);

z14=z13 shifted moveup; z141=z14 shifted moveright;
drawnormalD(14, 141);

z15=z14 shifted moveup; z151=z15 shifted moveright;
drawnormalCA(15, 151);

z16=z15 shifted moveup; z161=z16 shifted moveright;
drawnormalOA(16, 161);

z17=z16 shifted moveup; z171=z17 shifted moveright;
drawnormalF(17, 171);

%    \end{macrocode}
%
%    The upper part of the diagram illustrates some of the additional
% line styles and boxes provided that are not part of the
% \ExpressG{} language. 
% \changes{v1.1}{1999/10/30}{Extended upper half of diagram 1 for new box
%  types}
%
%    The upper half is seperated from the bottom half by a dashed line, just
% to make the distinction. The line is set above the highest box so far,
% which is located at |z8|, and extends across the width of the diagram.
%    \begin{macrocode}
z300=(0,y8tm+diam); z301=(x111,y300);
draw z300--z301 dashes;

%    \end{macrocode}
% Define |mup| to be a distance, which we will use for vertical seperation.
%    \begin{macrocode}
numeric mup; mup := onelineh;

%    \end{macrocode}
%
%    As previously, we'll start with the boxes which will be placed in
% a column at the left side of the diagram. The first box, high enough
% for one line of enclosed text, has its top right hand corner folded 
% down by one quarter the box height. Text is placed at the center
% of the box, but if this is not required then it can be given as an
% empty string (i.e., |""|).
%    \begin{macrocode}
z302=(0,y300+mup);
drawcardbox(302, pconl, onelineh, 1/4onelineh)("");

%    \end{macrocode}
%
% The next box is a diamond shape. Unlike the rectangular and rhomboidal
% boxes, these are positioned
% via the center of the box instead of the bottom left hand corner.
%    \begin{macrocode}
z303bm=(x302tm, y302tm+mup);
drawdiamondbox(303, pconl, 2onelineh)(btex jewel etex);

%    \end{macrocode}
%
%   Now there is a double box with the top portion being 3/4 of the box 
% height. Text is put into the top half of the box using \Mpost's
% labeling routine (see \pref{page:label}).
%    \begin{macrocode}
z304=(0, y303tm+mup);
drawdoublerectangle(304, pconl, 2onelineh, 3/4);
label(btex top etex, z304ct);

%    \end{macrocode}
%
%   Next comes a triple box with the bottom portion being one fifth of
% the height, and the top portion being two fifths of the height.
% Text is placed in the top and middle portions, but not into the bottom.
%    \begin{macrocode}
z305=(0, y304tm+mup);
drawtriplerectangle(305, pconl, 3onelineh, 2/5, 0.2);
label(btex top etex, z305ct);
label("middle", z305cm);

%    \end{macrocode}
%
%   Some languages include a box that looks a little like an index card, and
% this is shown next.
% A small box is also drawn inside the main part of the index box, 
% just to illustrate
% that drawings may be placed inside boxes.
%    \begin{macrocode}
z306=(0,y305tm+mup);
drawindexbox(306, 2pconl, 3onelineh, 3/4pconl, onelineh)(btex pack etex);
z307=1/8[z306bl,z306tr];
drawENT(307, 1/4pconl, onelineh)(btex E etex);

%    \end{macrocode}
%
% Another box shown here is a dotted box that covers up anything that
% is underneath it. To demonstrate, a folded corner box is drawn first, 
% and then the
% dashed box is drawn second. They have to be done in this order.
% (The reason for the notation |y306P.tl| is explained under diagram 2
% on \pref{page:dotsuffix}).
%    \begin{macrocode}
z308=(0, y306P.tl+mup);
z309ml=z308c;
drawcardbox(308, pconl, 2onelineh, 1/4onelineh)(btex covered etex);
drawdashboxover(309, pconl, onelineh);

%    \end{macrocode}
%
%    An oval box comes next. The perimeter is an ellipse.
%    \begin{macrocode}
z310bm=(x306bm,y309tm+mup);
drawovalbox(310, 2pconl, 2onelineh)("");

%    \end{macrocode}
%
%    Now we have two rounded boxes. In the first one the corner radius is
% small and the corners are neatly rounded. The radius is large in the
% second case, and it is automatically reduced to give semicircular ends.
% Further, the center portion of the second of these boxes is `deleted'
% by putting a |hiderectangle| over it.
%    \begin{macrocode}
z311ml=(x310mr+mup, y310ml);
drawroundedbox(311, 2pconl, 2onelineh, 1/2onelineh)("rounded");

z312ml=(x311mr+mup, y311mr);
drawroundedbox(312, 2pconl, 2onelineh, 3/2onelineh)(btex large radius etex);

z314=(x312bm-1/4pconl, y312bm-1/2mup);
hiderectangle(314, 1/2pconl, (3/2onelineh + mup));

%    \end{macrocode}
%
%    The last of the simple enclosed shapes are a dashed ellipse and a dashed circle,
% which are aligned below the partially obscured rounded box.
%    \begin{macrocode}
z315tm=(x312bm, y312bm-mup);
drawdashellipse(315, 2pconl, 2onelineh);

z316tm=(x315bm, y315bm-mup);
drawdashcircle(316, diam);

%    \end{macrocode}
%
%    A drum box is now presented. This is centered with respect to the 
% rounded box and aligned with the bottom of the triple box. It is the
% same nominal size as the triple box.
%    \begin{macrocode}
z317bc=(x311bm,y304br);
drawdrum(317, pconl, 3onelineh)(btex drum etex);
%    \end{macrocode}
% To be a little different, I'll add a `handle' to the top of the drum. The
% top of the handle will be above the drum at the point |z317A|, and the
% attachement points are at the |tml| and |tmr| points on the drum. The
% normally sharp join in the middle of the handle is smoothed off.
%    \begin{macrocode}
z317A=(x317tc, y317tc+2onelineh);
drawnormalthree(317tml, 317A, 317tmr);
smooth(317tml, 317A, 317tmr);

%    \end{macrocode}
%
% Below the drum box is a stick figure. It is centered with respect to the
% drum box and based on the bottom row.
% \changes{v1.6}{2004/02/29}{Added stickman to example drawing}
%    \begin{macrocode}
z320bm = (x317bm, y302);
drawstickman(320, onelineh, 2onelineh);

%    \end{macrocode}
%
%   Above the drum box there is an output box, vertically aligned with the
% stick figure, labelled `output'.
% \changes{v1.6}{2004/02/29}{Added output box to example drawing}
%    \begin{macrocode}
z325bm = (x320bm, y306);
drawoutputbox(325, pconl, 2onelineh)(btex output etex);

%    \end{macrocode}
%
%   Above the output box there is a simple circled dot.
% \changes{v1.6}{2004/02/29}{Added circled dot to example drawing}
%    \begin{macrocode}
z330 = (x320bm, y309ml);
drawCircledDot(330, 3/2onelineh);

%    \end{macrocode}
%
%    As in the bottom half, line styles are drawn on the right side of
% of the diagram. First, though, there is an arrowed circle symbol.
% This is vertically aligned with the centers of the lines.
%    \begin{macrocode}
z401bm=(1/2[x11,x111], y301+mup);
drawcircleA(401, diam);

%    \end{macrocode}
%
%    Finish off with assorted linestyles.
%    \begin{macrocode}
z402=(xmid, y401tm+mup); z502=(x111, y402);
drawdashA(402, 502);

z403=(xmid, y402+mup); z503=(x111, y403);
drawdashOA(403, 503);

z404=(xmid, y403+mup); z504=(x111, y404);
drawnormalOD(404, 504);

z405=(xmid, y404+mup); z505=(x111, y405);
drawnormalCD(405, 505);

z406=(xmid, y405+mup); z506=(x111, y406);
drawnormalDCA(406, 506);

%    \end{macrocode}
%
%    Lines can be drawn at any angle, and the non-circular line end styles
% remain aligned.
%    
%    A set of lines and endstyles are drawn rotating about the common
% start point of the lines.
% \DescribeRoutine{rotatedaround}
% |pt1 rotatatedaround(pt2, ang)| is \Mpost{} code that rotates
% the point |pt1| around the point |pt2| counterclockwise through the angle 
% |ang| in degrees.
%
%    \begin{macrocode}
numeric ang; ang = 180/7;
z600=(xmid, y406+2mup);
z699=(x600+len, y600);
z601=z699 rotatedaround(z600, ang);
z602=z699 rotatedaround(z600, 2ang);
z603=z699 rotatedaround(z600, 3ang);
z604=z699 rotatedaround(z600, 4ang);
z605=z699 rotatedaround(z600, 5ang);
z606=z699 rotatedaround(z600, 6ang);
z607=z699 rotatedaround(z600, 7ang);
drawnormalCA(600,601);
drawnormalOA(600,602);
drawnormalF(600,603);
drawdashA(600,604);
drawnormalOD(600,605);
drawnormalCD(600,606);

%    \end{macrocode}
%
%    This is the end of the first diagram.
%    \begin{macrocode}
endfig;   % end figure 1

%    \end{macrocode}
%
% \subsection{Diagrams 2--5: EXPRESS-G like models}
%
%    The diagrams in this section are all drawn using the \ExpressG{}
% specific routines. Nevertheless, they do illustrate general BLA techniques.
%
% \subsubsection{Diagram 2: Schema level diagram}
%
%    In contrast to the first diagram, this one is much more like an 
% \ExpressG{} diagram. It illustrates a diagram consisting of SCHEMA
% boxes and interconnections.
%
%    \begin{macrocode}
beginfig(2)                       % schema level model

%    \end{macrocode}
%
%    First define some lengths to assist in laying out the diagram, which is
% going to consists of three rows of boxes with varying numbers of boxes
% in each row; the bottom row has two, the middle has four, and the top row
% has one. We also want to align the boxes vertically in a `nice' manner.
%
%    \begin{macrocode}
numeric lb, hb;                 % length & height of boxes
lb=20u; hb=schemah;
numeric upshift;                % vertical distance between rows
upshift = 20u;
numeric sideshift;              % horizontal distance between boxes
sideshift = 10u;

%    \end{macrocode}
%
%    The bottom row has two boxes and the second four. The two bottom boxes
% will be aligned vertically under the two middle boxes in the middle row.
% Allowance must be made for a `missing' box at the start of the bottom
% row. The second box on the bottom row is spaced from the first one. 
%    \begin{macrocode}
%%% bottom row

z9=(lb+sideshift,0); 
drawSCHEMA(9, lb, hb)("nine"); 

z11=(x9br+sideshift,y9); 
drawSCHEMA(11, lb, hb)("eleven"); 

%    \end{macrocode}
%
%    The bottom of the boxes on the second row are all at a fixed distance
% above the top of the boxes on the first row. We only need to specify the
% y coordinate of the bottom of one box in the row, and use that for the 
% remainder,
%    \begin{macrocode}
%%% middle row

z1=(0,y9tl+upshift); 
drawSCHEMA(1, lb, hb)("one"); 

z3=(x1br+sideshift, y1); 
drawSCHEMA(3, lb, hb)("three"); 

z5=(x3br+sideshift, y1); 
drawSCHEMA(5, lb, hb)("five");  

z7=(x5br+sideshift, y1); 
drawSCHEMA(7, lb, hb)("seven"); 

%    \end{macrocode}
%
%    The single box on the top row will be position centrally above the
% two middle boxes of the middle row. Mediation is used to calculate
% the x coordinate that is halfway between the right side of the left
% box and the left side of the right box.
%    \begin{macrocode}
%%% top row

x50 = 1/2[x3br,x5bl];
z31bm=(x50,y1tl+upshift); 
drawSCHEMA(31, lb, hb)("thirtyone"); 

%    \end{macrocode}
%
%    This completes the boxes. The diagram is finished off by drawing 
% connections between the boxes. The first set of connections are just
% straight lines between known points on boxes.
%    \begin{macrocode}
%%% connectors

drawdashOO(9tm, 3bm);   % three/nine 
drawdashO(5bm, 11tm);   % five/eleven 
drawdashO(3ml, 1mr);    % three/one 
drawdashO(3mr, 5ml);    % three/five 
drawdashOO(9mr, 11ml);  % nine/eleven

%    \end{macrocode}
%
%    The next connection is more complex. It goes from schema thirtyone 
% to schema nine on a three-legged route. It goes horizontally left from
% thirtynine, then vertically down, and finally horizontally right to nine. It
% also passes to the left of schema one. 
%
%    The route is constructed by specifying a point |z90| to the left of
% schema nine, and the point |z31A| on the left hand of schema thirtynine.
% The |VH| routine is then called to generate the corner point on the 
% (rotated) L shaped path between |z90| and |z31A|. The connection is then
% drawn using these four points.
%    \begin{macrocode}
%%% thirtyone/nine 
z90=((x1bl-sideshift), y9ml);
z31A=3/4[z31bl,z31tl];
VH(90, 31A);
drawdashO(90vh, 31A);
drawdashthreeO(90vh, 90, 9ml);
%    \end{macrocode}
%
% \DescribeRoutine{pickup}
%    To demonstrate another aspect of \Mpost, a dot is drawn at the location
% of |z90|. If the drawing pen is thick enough, just drawing one point is
% sufficient to make a noticeable dot. The code |pickup thickpen;| drops
% the current pen and picks up 
% the thickpen for drawing. The code |pickup normalpen;| picks up the
% normal pen, which is the one that is normally used.
%
% \DescribeRoutine{label}
% \DescribeRoutine{dotlabel}
%    The last line of code here is |label.lft("z90", z90);| which puts the
% text `z90' at the left of point |z90|.\label{page:label} 
% The label routine has two arguments,
% the first the text and the second the point at or near which the text is
% to be placed. The simplest form of the routine is |label("text", zk)| which
% centers the text over the point |zk|. A
% suffix can be used after the |label| (e.g., |.lft| in the code below) to
% modify the placement. |.lft| positions the text at the left of the point.
% The other modifiers are: |.rt|, |.top|, |.bot|, |.ulft|, |.urt|, |.llft| and
% |.lrt|. There is also a |dotlabel.suffix("text", zk)| routine which draws
% the point as well. For complicated diagrams it can be useful to label 
% some points during development, and then comment them out for the final 
% picture.
%    \begin{macrocode}
pickup thickpen;
draw z90;
pickup normalpen;
label.lft("z90", z90);

%    \end{macrocode}
%
%    The next two connectors, between schemas one and eleven and between
% thirtyone and eleven are of a similar U shape. There is, though, one tricky
% point to remember. Up till now, all point arguments to the \Lpack{expressg} 
% routines have been of the form |3| or |4bm|; 
% that is, either a number or a number
% followed by letter(s). For example, |VH(3,4bm)| will calculate
% the point |z3vh|. However, if a routine adds more letters to an argument
% that already has letters, such as |VH(4bm,3)|, the calculated point is 
% \emph{not} |z4bmvh| as might be expected, but instead 
% is |z4bm.vh|.\label{page:dotsuffix}
% This has tripped me up on several occasions.
%    \begin{macrocode}
%%% one/eleven 
z1A=1/3[z1bl,z1br];
z11A=(x11bm, (y11bm-sideshift));
VH(1A, 11A);
drawdashthree(1A, 1A.vh, 11A);   % note it is 1A.vh and not 1Avh
drawdashO(11A, 11bm);
dotlabel.rt("z11A", z11A);
dotlabel.lft("z1A.vh", z1A.vh);   % note it is z1A.vh and not z1Avh

%    \end{macrocode}
%
%    The connector between thirtyone and eleven is the same general shape
% as the thirtyone to nine connector. This time, I'll use the |HxH| routine
% to calculate the turning points
%    \begin{macrocode}
%%% thirtyone/eleven 
z31B=3/4[z31br,z31tr];
x31BC=x7br+sideshift;
HxH(31B, 31BC, 11mr);
drawdashfourO(31B, 31B.hxh, 11mr.hxh, 11mr);

%    \end{macrocode}
%
%    The next two connectors, between thirtyone and seven, and between 
% thirtyone and one, are simple L shapes, which are easier to produce than the
% U shaped ones.
%    \begin{macrocode}
%%% thirtyone/seven 
z31D=1/4[z31br,z31tr];
VH(7tm, 31D);
drawnormalthreeO(31D, 7tm.vh, 7tm);

%%% thirtyone/one 
z31C=1/4[z31bl,z31tl];
VH(1tm, 31C);
drawdashO(1tm.vh, 31C);
drawdashO(1tm.vh, 1tm);

%    \end{macrocode}
%
% The last two connectors are also simple, each consisting of vertical then 
% horizontal then vertical lines and the turning points can be calculated 
% by the |VhV| routine..
%    \begin{macrocode}
%%% thirtyone/three 
z31E=1/4[z31bl,z31br];
VhV(31E, 3tm);
drawnormalfourO(31E, 31E.vhv, 3tm.vhv, 3tm);

%%% thirtyone/five 
z31F=3/4[z31bl,z31br];
VhV(31F, 5tm);
drawnormalfourO(31F, 31F.vhv, 5tm.vhv, 5tm);

%    \end{macrocode}
%
%    The last element in the diagram is a vertical closed arrowheaded line
% with a label alongside. The arrowhead is on the top line of the connector
% between thirtyone and eleven. Note the point mediation expression expression
% in the |label| routine call.
%    \begin{macrocode}
%%% labeled arrow
z3111=1/4[z31B,z31B.hxh];
numeric arrowsize;
arrowsize := schemah;
z3112=(x3111, y3111+arrowsize);
drawnormalCA(3112, 3111);
label.rt(btex an\_import etex, 1/2[z3111, z3112]);

%    \end{macrocode}
%
%    The end of this diagram.
%    \begin{macrocode}
endfig;  % end fig 2

%    \end{macrocode}
%
%
% \subsubsection{Diagram 3: Tree structure}
%
%    This diagram is the first of three that are related in style. It is
% useful at this point to define some variables, and values for some of
% these as they will probably be used in all three diagrams.
%
%    Values are assigned (e.g., |var := val;|) so that they can be changed
% later if necessary (e.g., |var := newval;|). If values were equated like
% |var = val;| then they cannot be changed afterwards\footnote{Except
% by assignment.} as |var = newval;|
% will then have specified two incompatible equations for |var| and \Mpost will
% report a problem.
%    \begin{macrocode}

%%%% some commonly used variables & values

numeric pl, ph;           % length & height of numeric page connectors
pl:=pconl; ph:=pconh;     % for eg., 9,9 (9,9)
numeric plnamed;          % length of named page connector
numeric irh;              % height of interschema boxes
irh:=ish;                 % normally one line of text
numeric sdtl, sdth;       % length & height of SDT (e.g. INTEGER) boxes
sdtl:=sdtbl; sdth:=sdtbh;
numeric edtl, edth;       % length & height of enum boxes (inset is sdtbs)
edth:=sdtbh;              % normally one text line
numeric el, eh;           % length & height of entity boxes
eh:=enth;                 % normally one text line
numeric upshift;          % vertical space between rows of boxes
numeric nextup;           % vertical space between bases of rows of boxes
%    \end{macrocode}
%
%    Now another bit of \Mpost. There is another type of variable called
% a |picture| variable. This can hold something as trivial as a dot or
% a text string, up to a complete diagram. References to an Index
% type is a common element in some of the diagrams. It is useful to
% create a shorthand for these by using picture variables.
%    \begin{macrocode}
picture sindex, pindex;
sindex := btex eleven.Index etex;      % interschema reference text
pindex := btex 9,9 Index etex;         % page reference text
numeric slindex, plindex;
slindex := namespace(sindex)(nextra);  % length of Index interschema 
plindex := namespace(pindex)(nextra);  % length of Index page reference
%    \end{macrocode}
%
%    Yet more new \Mpost. Array variables are supported. These are declared
% by giving the variable name immediately followed by a pair of square 
% brackets. An element of an array can be simply accessed by suffixing the
% variable name with the integer number denoting the desired position.
% Actually we have been using array variables all along, as |z3| or |x7|
% are elements of the arrays |z[]| and |x[]| respectively. We define
% two arrays, one to be used for specifying horizontal spaces (lengths)
% and the other for vertical (y) coordinates. 
%    \begin{macrocode}
numeric hspace[];         % horizontal spaces
numeric lyc[];            % Y coords of box bases

%%%%%%%%%%% end commonly used variables & values

%    \end{macrocode}
%
% Diagram 3 consists of type boxes. We will make these all the same length
% and height.
%    \begin{macrocode}
beginfig(3)                      % example fig 3 
%%%drawgrid;

%    \end{macrocode}
%
%    The space required for the longest name is |edtl|.
%    \begin{macrocode}
edtl := namespace(btex standard\_data\_name etex)(niextra);
%    \end{macrocode}
%
%    There are several rows in the diagram. Specify the vertical space
% between the rows, and the space between the bottoms of the boxes (the
% height of a box is the normal height, |sdth|,  for a type box). Also
% specify the y coordinates for each row, counting from the bottom.
%    \begin{macrocode}
upshift=2sdth;
nextup=sdth+upshift;
%%%        the y coords of box bases
lyc1:=0;
lyc2:=lyc1+nextup;
lyc3:=lyc2+nextup;
lyc4:=lyc3+nextup;
lyc5:=lyc4+nextup;
lyc6:=lyc5+nextup;
lyc7:=lyc6+nextup;
lyc8:=lyc7+nextup;
%    \end{macrocode}
% Specify two horizontal spaces.
%    \begin{macrocode}
hspace1 := 1/3edtl;  % space between data enums
hspace2 := 2/3edtl;  % initial space at start of second row

%    \end{macrocode}
%    Draw the 3 boxes in the first row and the 3 in the second; these are
% staggered with respect to each other and overlap as otherwise there
% there is not enough space to get them all onto one page. 
% I'll use a numbering scheme for
% points so that |zCR| is a point in the Cth column and the Rth row.
%    \begin{macrocode}
%%% bottom two rows (1 & 2)

z11=(0,lyc1);
drawENUM(11, edtl, edth)(btex coordinates etex);

z22=(hspace2, lyc2);
drawENUM(22, edtl, edth)(btex solution\_data etex);

z31=(x11br+hspace1, lyc1);
drawENUM(31, edtl, edth)(btex pressure\_loads etex);

z42=(x22br+hspace1, lyc2);
drawENUM(42, edtl, edth)(btex nondimensional etex);

z51=(x31br+hspace1, lyc1);
drawENUM(51, edtl, edth)(btex temperature etex);

z62=(x42br+hspace1, lyc2);
drawENUM(62, edtl, edth)(btex force\_loads etex);

%    \end{macrocode}
%
% The third `row' consists of a horizontal line stretching from the middle
% of the leftmost box to the middle of the rightmost box. There are 
% connections from this line to the top middle of each of the boxes. We can
% use the |VyV| routine for the end points of the line.
%    \begin{macrocode}
%%% third row (horizontal line between 2 & 4 row)

z13=(x11tm,lyc3); 
VyV(11tm, 13, 62tm);
drawnormal(11tm.vyv, 62tm.vyv);
%    \end{macrocode}
%
%    Calculate the points on this line vertically above the midpoints of
% the boxes and draw the connections.
%    \begin{macrocode}
z23=(x22tm,lyc3); z33=(x31tm,lyc3); z43=(x42tm,lyc3); z53=(x51tm,lyc3);
drawnormalO(11tm.vyv,11tm);
drawnormalO(23,22tm);
drawnormalO(33,31tm);
drawnormalO(43,42tm);
drawnormalO(53,51tm);
drawnormalO(62tm.vyv,62tm);

%    \end{macrocode}
%
%    The fourth row consists of three boxes. There is a vertical line 
% from the bottom
% of the leftmost box to the horizontal line drawn in row 4. The three
% boxes are aligned horizontally with respect to this line.
%    \begin{macrocode}
%%% fourth row 

z3224=1/3[z13,z62tm.vyv];
z3554=2/3[z13,z62tm.vyv];

%%% standard_data_name
z24bm=(x3224,lyc4);
drawSELECT(24, edtl, edth)(btex standard\_data\_name etex);
drawnormal(24bm,3224);

%%% adhoc_data_name
z54bm=(x3554,lyc4);
drawTYPE(54, edtl, edth)(btex adhoc\_data\_name etex);

%%% STRING
z64br=(x62br,lyc4);
drawSTRING(64);

%    \end{macrocode}
%
%    The fifth `row' consists of two vertical connectors to the tops of
% the SELECT and TYPE boxes, with a horizontal line connecting the tops
% of the connectors.
%    \begin{macrocode}
%%% fifth row

z35=(1/2[x24tm,x54tm], lyc5);
VyV(24tm, 35, 54tm);
drawnormalthreeO(35, 24tm.vyv, 24tm);
drawnormalthreeO(35, 54tm.vyv, 54tm);

%    \end{macrocode}
%
%    The top row consists of a SELECT box vertically aligned above the center
% of the horizontal line from the 5th row, together with a line joining
% these two, and also a page reference box
% off towards the right hand side
%    \begin{macrocode}
%%% sixth row

z36bm=(x35,lyc6);
drawSELECT(36,edtl, edth)(btex data\_name etex);
drawnormal(36bm,35);

%%% data_name
z66=(x62,lyc6);
drawPREF(66, sdtl, ph)(btex 3,1 (4) etex);

%    \end{macrocode}
%
%    The remaining elements on the diagram are: 
% a connector on the 4th row from adhoc\_data\_name to STRING;
% and a connector on the 6th row from the page reference to data\_name.
%    \begin{macrocode}
%%%% rest of the connectors 

%%% adhoc/STRING (54, 64)
drawnormalO(54mr,64ml);

%%% PREF/data_name (36, 66)
drawdashO(66ml,36mr);

%    \end{macrocode}
%
%    The end of this diagram
%    \begin{macrocode}
endfig;                         % end fig 3

%    \end{macrocode}
%
% \subsubsection{Diagram 4: Supertypes and subtypes}
%
%    This diagram consists of a supertype entity and its four subtypes. The
% entities have various attributes.
%
%    \begin{macrocode}

beginfig(4)                     % example 4 
%%%drawgrid;

%    \end{macrocode}
%
%    Define some useful lengths.
%    \begin{macrocode}
%%% length of named page reference boxes
plnamed := namespace(btex 9,9 data\_name etex)(nextra);

%%% length of entity boxes
el := namespace(btex (ABS) Data\_t etex)(nextra);

upshift := 2sdth;         % vertical space between boxes
nextup := sdth+upshift;   % vertical space between bases of boxes
hspace1 := 1/2el;         % space between entity boxes

%%% the y coords of box bases
lyc1:=0;
lyc2:=lyc1+nextup;
lyc3:=lyc2+nextup;
lyc4:=lyc3+nextup;
lyc5:=lyc4+nextup;
lyc6:=lyc5+nextup;
lyc7:=lyc6+nextup;
lyc8:=lyc7+nextup;

%    \end{macrocode}
%
%    We'll start with the second row which consists of 4 entity (subtype)
% boxes. The numbering scheme for point suffixes is |zCR|, where |C|
% is the column number and |R| is the row number.
%    \begin{macrocode}
%%%% 2nd row

%%% IntArray
z12=(0,lyc2);
drawENT(12, el, eh)(btex IntArray etex);

%%% RealArray
z22=(x12br+hspace1, lyc2);
drawENT(22, el, eh)(btex RealArray etex);

%%% CharArray
z42=(x22br+hspace1, lyc2);
drawENT(42, el, eh)(btex CharArray etex);

%%% BitArray
z52=(x42br+hspace1, lyc2);
drawENT(52, el, eh)(btex BitArray etex);

%    \end{macrocode}
%
%    The first row is four simple data type boxes, aligned underneath the
% entity boxes.
%    \begin{macrocode}
%%%% 1st row

z11bm=(x12bm,lyc1);
drawINTEGER(11);

z21bm=(x22bm,lyc1);
drawREAL(21);

z41bm=(x42bm,lyc1);
drawSTRING(41);

z51bm=(x52bm,lyc1);
drawBINARY(51);

%    \end{macrocode}
%
%    The third `row' is the thick lines connecting the subtype boxes.
%    \begin{macrocode}
%%% 3rd row

y13=       y23=       y43=       y53=lyc3;
x13=x12tm; x23=x22tm; x43=x42tm; x53=x52tm;
drawthick(13,53);      % horizontal line
%%% vertical connectors
drawthickO(13,12tm); drawthickO(23,22tm); 
drawthickO(43, 42tm); drawthickO(53, 52tm);

z33=1/2[z13,z53];   % midpoint of horizontal line

%    \end{macrocode}
%
%    The 4th row is an abstract supertype entity box, which is made 3 times
% taller than the default entity box height. The entity box is centered 
% with respect to the row of subtype boxes and is connected to the
% subtype boxes connector. The digit 1 is placed near the connection point.
%  There is also a page reference
% and an INTEGER box at the left and right (as attributes of the supertype).
%    \begin{macrocode}
%%% 4th row

%%% Data_t
z34bm=(x33,lyc4);
drawENT(34, el, 3eh)(btex \twolines{(ABS)}{Data\_t} etex);
drawthick(34bm,33);
label.urt("1", z33);   % label the connection point

%%% Index
z14=(0,lyc4);
drawPREF(14, plindex, ph)(pindex);

%%% INTEGER
z54br=(x51br,lyc4);
drawINTEGER(54);

%    \end{macrocode}
%
%    The 5th row has page reference boxes at the left and right 
% (as attributes of the supertype).
%    \begin{macrocode}
%%% 5th row

lyc5:=y34tm-ph;   % change the initial y coord value

%%% Index
z15=(0,lyc5);
drawPREF(15, plindex, ph)(pindex);

%%% DataType
z55=(x54,lyc5);
drawPREF(55, plnamed, ph)(btex 3,1 data\_name etex);

%    \end{macrocode}
%
%    The 6th, and last, row, just consists of a page reference centered
% above the supertype box.
%    \begin{macrocode}
%%% 6th row

%%% PREF to Data_t
lyc6:=lyc5+nextup;
z36bm=(x34tm,lyc6);
drawPREF(36, pl, ph)(btex 7,5 (6) etex);

%    \end{macrocode}
%
%    The rest of the diagram consists of the labelled attribute lines.
%    \begin{macrocode}
%%%% attributes

%%% Sizes  Data_t/Index (34, 14)
z3414=(x34,y14mr);
drawnormal(3414,14mr);
label.ulft(btex Sizes A[1:Limit] etex, z3414);

%%% num  Data_t/INTEGER (34, 54)
z3454=(x34mr,y54ml);
drawnormalO(3454,54ml);
label.urt(btex (DER) num etex, z3454);

%%% Limit Data_t/Index (34, 15)
z3415=(x34,y15mr);
drawnormal(3415,15mr);
label.ulft(btex Limit etex, z3415);

%%% Kind Data_t/data_name (34, 55)
z3455=(x34mr, y55ml);
drawnormal(3455, 55ml);
label.urt(btex Kind etex, z3455);

%%% PREF into Data_t (36, 34)
drawdashO(36bm, 34tm);

%%% Data IntArray/INTEGER (12, 11)
drawnormalO(12bm, 11tm);
label.lrt(btex Data A[1:num] etex, z12bm);

%%% Data RealArray/REAL (22, 21)
drawnormalO(22bm, 21tm);
label.lrt(btex Data A[1:num] etex, z22bm);

%%% Data CharArray/STRING (42, 41)
drawnormalO(42bm, 41tm);
label.lrt(btex Data A[1:num] etex, z42bm);

%%% Data BitArray/BINARY (52, 51)
drawnormalO(52bm, 51tm);
label.lrt(btex Data A[1:num] etex, z52bm);

%    \end{macrocode}
%
%     The end of this diagram.
%    \begin{macrocode}
endfig;                              % end fig 4

%    \end{macrocode}
%
%    \subsubsection{Diagram 5: Portion of larger model}
%
%    This diagram is more complex than the previous ones. It is, nevertheless,
% presented with virtually no commentary. It consists of three entity boxes
% and various page reference and interschema boxes to support the
% entities' attributes.
%
%    \begin{macrocode}
beginfig(5)                 % example 5 
%%drawgrid;

%    \end{macrocode}
%
%    As usual, specify commonly used variables and values.
%    \begin{macrocode}
plnamed := namespace(btex 7,4 Unstructured\_Donor etex)(nextra);

numeric irls, irll;             % length of short and long ISR boxes
irls = namespace(btex eleven.MeshLocation etex)(nextra);
irll = namespace(btex eleven.MeshConnectivityType etex)(nextra);

upshift := irh;
nextup := irh+upshift;

numeric maxrx;         % max x coordinate value of LH of right column boxes
maxrx := maxx-irrl; 
numeric xmid;          % x coord of figure center
xmid := 1/2[irls, maxx-irll];

el := namespace(btex MeshConnectivity1\_1 etex)(nextra);
eh := irh;

%%% y coords
lyc1 := 0;
lyc2 := lyc1+nextup;
lyc3 := lyc2+nextup;
lyc4 := lyc3+nextup+irh;
lyc5 := lyc4+nextup;
lyc6 := lyc5+nextup;
lyc7 := lyc6+nextup;
lyc8 := lyc7+nextup;
lyc9 := lyc8+nextup;

%    \end{macrocode}
%
%    Rows one and two have one centered box each.
%    \begin{macrocode}
%%% Zcol/row
%%% row 1

%%% PREF for Overlapping
z21bm=(xmid,lyc1);
drawPREF(21, pl, ph)(btex 5,3 (8) etex)

%%% row 2

%%% OverlappingArea
z22bm=(x21bm,lyc2);
drawENT(22, el, eh)(btex OverlappingArea etex);

%    \end{macrocode}
%
%    Row three has three boxes, and the middle one is centered.
%    \begin{macrocode}
%%% row 3

%%% IndexArray
z13=(pl,lyc3);
drawISR(13, irls, irh)(btex eleven.IndexArray etex);

%%% Index
z23bm=(x22bm,lyc3);
drawISR(23, slindex, irh)(sindex);

%%% MeshLocation
z33br=(maxx,lyc3);
drawISR(33, irls, irh)(btex eleven.MeshLocation etex);

%    \end{macrocode}
%
%    Row four has three boxes, and the middle one is centered.
%    \begin{macrocode}
%%% row 4

%%% MeshConnectivity
z24bm=(x23bm,lyc4);
drawENT(24, el, eh)(btex MeshConnectivity etex);

%%% PREF for MeshConnectivity
z14ml=(pl,y24ml);
drawPREF(14, pl, ph)(btex 5,2 (8) etex);

%%% Structured_Donor
z34br=(maxx,lyc4);
drawPREF(34, plnamed, ph)(btex 7,5 Structured\_Donor etex);

%    \end{macrocode}
%
%    Rows five and six have one box each, at the right hand side.
%    \begin{macrocode}
%%% row 5

%%% Unstructured_donor
z35br=(maxx,lyc5);
drawPREF(35, plnamed, ph)(btex 7,4 Unstructured\_Donor etex);

%%% row 6

%%% MeshConnType
z36br=(maxx,lyc6);
drawISR(36, irll, irh)(btex eleven.MeshConnectivityType etex);

%    \end{macrocode}
%
%    Row seven has three boxes, and the middle one is centered.
%    \begin{macrocode}
%%% row 7

%%% IndexRange
z17=(0,lyc7);
drawISR(17, irls, irh)(btex eleven.IndexRange etex);

%%% INTEGER
x27bm=x24bm; y27ml=y17mr;
drawINTEGER(27);

%%% Zone
z37br=(maxx,lyc7);
drawISR(37, irls, irh)(btex seven.Zone etex);

%    \end{macrocode}
%
%    Rows eight and nine have one centered box each.
%    \begin{macrocode}
%%% row 8

%%% 1to1
z28bm=(x24bm,lyc8);
drawENT(28, el, eh)(btex MeshConnectivity1\_1 etex);

%%% row 9

%%% PREF to 1to1
z29bm=(x28bm,lyc9);
drawPREF(29, pl, ph)(btex 5,1 (8) etex);

%    \end{macrocode}
%
%    All the boxes have been drawn. The remainder is adding and labelling
% attribute lines. First page references to subtype entities.
%    \begin{macrocode}
%%%% attributes, etc

drawthickO(21tm,22bm);   % PREF to Overlap (21, 22)
drawthickO(14mr,24ml);   % PREF to MeshConn (14, 24)
drawthickO(29bm,28tm);   % PREF to 1to1 (29, 28)

%    \end{macrocode}
%
%    The attributes of entity OverlappingArea (|z22|)
%    \begin{macrocode}
%%% PointListSize (22, 23)
drawdashO(22tm,23bm);
label.llft(btex PointListSize etex, z23bm);

%%% PointRange (22, 17)
z22A=1/4[z22bl,z22tl]; z17A=(1/2[0,x13], y17);
VH(17A,22A);
drawdashthreeO(22A, 17A.vh, 17A);
label.ulft(btex PointRange etex, z22A);

%%% PointList (22, 13)
z22B=3/4[z22bl,z22tl];
VH(13bm,22B);
drawdashthreeO(22B, 13bm.vh, 13bm);
label.ulft(btex PointList etex, z22B);

%%% MeshLocation (22, 33)
z22C=1/4[z22br,z22tr];
z33B=2/3[z33bl,z33br];
VH(33B,22C);
drawnormalthreeO(22C, 33B.vh, 33B);
label.urt(btex (DER) Location etex, z22C);

%%% Meshloc (22, 33)
z22D=3/4[z22br,z22tr];
z33A=1/3[z33bl,z33br];
VH(33A,22D);
drawdashthreeO(22D, 33A.vh, 33A);
label.urt(btex Meshloc etex, z22D);

%    \end{macrocode}
%
%    The attributes of entity MeshConnectivity (|z24|).
%    \begin{macrocode}
%%% PointListSize (24, 23)
drawnormalO(24bm, 23tm);
label.ulft(btex PointListSize etex, z23tm);

%%% StructuredDonor (24, 34)
z24A=(x24br,y34ml);
draw z24A--z34ml dashes;
label.lrt(btex StructuredDonor etex, z24A);

%%% UnstructuredDonor (24, 35)
z24B=3/4[z24br,z24tr];
HvH(24B,35ml);
drawdashfourO(24B, 24B.hvh, 35ml.hvh, 35ml);
label.urt(btex UnstructuredDonor etex, z24B.hvh);

%%% Meshloc (24, 33)
z24C=4/6[z24bl,z24br];
z33C=(x33A,y33tm);
y2433C=1/3[y33C,y24C];
VyV(24C, 2433C, 33C);
drawdashfourO(24C, 24C.vyv, 33C.vyv, 33C);
label.lrt(btex Meshloc etex, z24C.vyv);

%%% Location (24, 33)
z24D=5/6[z24bl,z24br];
z33D=(x33B,y33tm);
y2433D=2/3[y33D,y24D];
VyV(24D, 2433D, 33D);
drawnormalfourO(24D, 24D.vyv, 33D.vyv, 33D);
label.lrt(btex (DER) Location etex, z24D.vyv);

%%% ConnectivityType (24, 36)
z24H=(x24D,y24tr); 
z36H=z36bm;
y2436H=1/2[y35tr,y36br];
VyV(24H, 2436H, 36H);
drawnormalfourO(24H, 24H.vyv, 36H.vyv, 36H);
label.urt(btex (DER) ConnectivityType etex, z24H.vyv);

%%% Meshcon (24, 36)
z24G=(x24C,y24tr);
z36G=z36ml;
VH(24G,36G);
drawdashthreeO(24G, 24G.vh, 36G);
label.urt(btex Meshcon etex, z24G.vh);

%%% K (24, 27)
drawnormalO(24tm, 27bm);
label.ulft(btex K etex, z24tm);

%%% PointRange (24, 17)
z24E=1/4[z24tl,z24tr];
x17br-x17E = x17A-x17bl;
y17E = y17A;
VhV(24E,17E);
drawdashfourO(24E, 24E.vhv, 17E.vhv, 17E);
label.ulft(btex PointRange etex, z24E);

%%% PointList (24, 13)
z24F=1/4[z24bl,z24br];
z13F=1/2[z13tl,z13tr];
VhV(24F,13F);
drawnormalfourO(24F, 24F.vhv, 13F.vhv, 13F);
label.llft(btex PointList etex, z24F);
 
%    \end{macrocode}
%
%    The attributes of entity MeshConnectivity1\_1 (|z28|)
%    \begin{macrocode}
%%% N (28, 27)
z27A=1/5[z27tl,z27tr];
z28A=(x27A,y28bl);
drawnormalO(28A,27A);
label.llft(btex N etex, z28A);

%%% trans (28, 27)
z27B=1/2[z27tl,z27tr];
z28B=(x27B,y28bl);
drawdashO(28B,27B);
label.lrt(btex \twolines{trans}{A[1:N]} etex, z28B);

%%% Transform (28, 27)
z27C=1/2[z27br,z27tr];
z28C=(1/2[x27C,x28br], y28br);
VH(28C,27C);
drawnormalthreeO(28C,28C.vh,27C);
label.lrt(btex (DER) Transform A[1:N] etex , z28C);

%%% DonorZone (28, 37)
z28D=1/2[z28br,z28tr];
z37D=z37tm;
VH(37D,28D);
drawdashthreeO(28D,37D.vh,37D);
label.urt(btex DonorZone etex, z28D);

%%% DonorPointRange (28, 17)
z28G=3/4[z28bl,z28tl];
z17G=(x17A,y17tl);
VH(17G,28G);
drawnormalthreeO(28G,17G.vh,17G);
label.ulft(btex DonorPointRange etex, z28G);

%%% PointRange (28, 17)
z28H=1/4[z28bl,z28tl];
z17H=(x17E,y17G);
VH(17H,28H);
drawnormalthreeO(28H,17H.vh,17H);
label.ulft(btex PointRange etex, z28H);

%    \end{macrocode}
%
%    The end of this diagram.
%    \begin{macrocode}
endfig;                             % end fig 5

%    \end{macrocode}
%
% \subsection{Diagrams 6--11: Car model}
%
%    The diagrams in this section are all taken from~\cite[Chapter~2]{EBOOK}.
% A simple information/data model of a car, car model, and car manufacturer
% is presented in a variety of BLA languages, among which is, 
% of course, \ExpressG. In words, the model is:
% \begin{quote} \itshape
%     A car is made by a manufacturer. Each manufacturer has a unique name.
% A manufacturer constructs cars in several models and a car is of a
% particular model. A manufacturer gives a serial number to each car 
% he produces and this is unique across all cars produced by that
% manufacturer. Each model also has a name, and this is unique across
% all models. A car has a year of production.
% \end{quote}
% This model is a small portion of a conceptual model developed as a common
% specification for comparing modeling languages~\cite{TR9007}.
%
% The purpose of these diagrams is to 
% illustrate how the \Lpack{expressg} package supports a range of graphical
% languages.
%
%
% \subsubsection{Diagram 6: \ExpressG}
%
%    Having already seen several examples of \ExpressG{} diagrams, this one
% is presented with no further comments.
%    \begin{macrocode}

beginfig(6)            % example 6  EXPRESS-G
%%%drawgrid;

upshift := 3/2onelineh;
nextup := onelineh+upshift;

el := namespace(btex manufacturer etex)(nextra);
eh := onelineh;

hspace1 := 1/2el;

%%% y coords
lyc1 := 0;
lyc2 := lyc1+nextup;
lyc3 := lyc2+nextup;
lyc4 := lyc3+nextup;
lyc5 := lyc4+nextup;

%%% Zcol/row

%%% rows 4 and 5
z14=(0,lyc4);
drawENT(14, el, eh)(btex manufacturer etex);

z25=(x14br+hspace1, lyc5);
drawSTRING(25);

z34=(x25br+hspace1, lyc4);
drawENT(34, el, eh)(btex car\_model etex);

%%% row 3

z33bm=(x34bm, lyc3);
drawENT(33, el, eh)(btex car etex);

%%% row 2

z22=(x25, lyc2);
drawINTEGER(22);

%%% row 1

z21=(x22, lyc1);
drawSTRING(21);

%%% attributes

%%% manufacturer name (14, 25)
VH(14tm, 25ml);
drawnormalthreeO(14tm, 14tm.vh, 25ml);
label.urt(btex *name etex, z14tm.vh);

%%% model name (34, 25)
VH(34tm, 25mr);
drawnormalthreeO(34tm, 34tm.vh, 25mr);
label.ulft(btex *name etex, z34tm.vh);

%%% made_by (34, 14)
drawnormalO(34ml, 14mr);
label.ulft(btex made\_by etex, z34ml);

%%% model_type (33, 34)
drawnormalO(33tm, 34bm);
label.urt(btex model\_type etex, z33tm);

%%% DER made_by (33, 14)
VH(14bm, 33ml);
drawnormalthreeO(33ml, 14bm.vh, 14bm);
label.ulft(btex (DER) *made\_by etex, z33ml);

%%% year (33, 22)
z33A=1/3[z33bl, z33br];
VH(33A, 22mr);
drawnormalthreeO(33A, 33A.vh, 22mr);
label.ulft(btex year etex, z33A.vh);

%%% serial_no
z33B=2/3[z33bl, z33br];
VH(33B, 21mr);
drawnormalthreeO(33B, 33B.vh, 21mr);
label.ulft(btex *serial\_no etex, z33B.vh);

%    \end{macrocode}
%
% The end of this diagram
%    \begin{macrocode}
endfig;               % end fig 6

%    \end{macrocode}
%
%
% \subsubsection{Diagram 7: Shlaer-Mellor}
%
%    The Shlaer-Mellor graphical language~\cite{SHLAER88} is fairly simple,
% consisting basically of rectangles and arrowheaded lines. However, unlike
% \ExpressG{} each box usually has several lines of text. These are placed
% individually at the desired positions within each box.
%
%    Notice below that
% I have used |drawENT| with an empty string to draw the rectangular boxes;
% the routines for \ExpressG{} diagrams can, if suitable, be used in any
% sort of diagram.
%
%    \begin{macrocode}

beginfig(7)            % example 7
%%%drawgrid;

el := namespace(btex MANUFACTURER etex)(niextra);
eh := onelineh;

hspace1 := namespace(btex made by maker of etex)(4ndextra);

hspace2 := 6onelineh;   % height of CAR
hspace3 := 5onelineh;   % space between rows
hspace4 := 3onelineh;   % height of MANUFACTURER

%%% y coords
lyc1 := 0;
lyc2 := lyc1+hspace2+hspace3;

%%% Zcol/row

%%% row 2

z12=(0, lyc2);
drawENT(12, el, hspace4)("");
x121=x12+sdtbs;
label.rt(btex MANUFACTURER etex, (x121, 2/3[y12bl, y12tl]));
label.rt(btex * manuf-name etex, (x121, 1/3[y12bl, y12tl]));

z22=(x12br+hspace1, lyc2);
drawENT(22, el, hspace4)("");
x221=x22+sdtbs;
label.rt(btex CAR-MODEL etex, (x221, 2/3[y12bl, y12tl]));
label.rt(btex * model-name etex, (x221, 1/3[y12bl, y12tl]));

%%% row 1

z21=(x22, lyc1);
drawENT(21, el, hspace2)("");
x211=x21+sdtbs;
label.rt(btex CAR etex,         (x211, 5/6[y21bl, y21tl]));
label.rt(btex o year etex,      (x211, 4/6[y21bl, y21tl]));
label.rt(btex o model (R) etex, (x211, 3/6[y21bl, y21tl]));
label.rt(btex * serial-no etex, (x211, 2/6[y21bl, y21tl]));
label.rt(btex * maker (R) etex, (x211, 1/6[y21bl, y21tl]));

%%%%% relationship lines

%    \end{macrocode}
% In this diagram the labels on the relationship lines tend to bump
% into the line ending symbol. \Mpost{} ignores initial and final spaces
% within |btex...etex|. The paired braces below, each enclosing one space,
%  supply non-discarded spaces. (These could also have been written as 
% |\space|).
%    \begin{macrocode}
%%% MANUFACTURER / CAR-MODEL (12, 22)
drawnormalDCA(12mr, 22ml);
drawnormalCA(22ml, 12mr);
label.urt(btex { }{ }made by etex, z12mr);
label.llft(btex maker of{ }{ } etex, z22ml);

%%% MANUFACTURER / CAR (12, 21)
VH(12bm, 21ml);
drawnormalCA(12bm.vh, 12bm);
drawnormalDCA(12bm.vh, 21ml);
label.llft(btex { }{ }made by etex, z12bm);
label.ulft(btex maker of{ }{ }  etex, z21ml);

%%% CAR-MODEL / CAR (22, 21)
drawnormalDCA(22bm, 21tm);
drawnormalCA(21tm, 22bm);
label.lrt(btex { }one of etex, z22bm);
label.ulft(btex type of{ }  etex, z21tm);

%    \end{macrocode}
%
% The end of this diagram
%    \begin{macrocode}
endfig;               % end fig 7

%    \end{macrocode}
%
%
% \subsubsection{Diagram 8: IDEF1X}
%
%    IDEF1X is a popular language in America for representing the structure
% of relational databases, and was developed under the auspices of the 
% US Air Force~\cite{IDEF1X}.
%
%    The general layout of the diagram mimics the previous one. All the boxes
% are divided horizontally into an upper and lower part. 
% The |drawdoublerectangle| is used for the rectangular boxes, but the dividing
% line in the rounded box has to be added by hand, as it were.
%
%    \begin{macrocode}

beginfig(8)            % example 8  IDEF1X
%%%drawgrid;

el := namespace(btex MANUFACTURER etex)(niextra);
eh := onelineh;

hspace1 := namespace(btex made by maker of etex)(4ndextra);

hspace2 := 5onelineh;   % height of CAR
hspace3 := 5onelineh;   % space between rows
hspace4 := 3onelineh;   % height of MANUFACTURER

%%% y coords
lyc1 := 0;
lyc2 := lyc1+hspace2+hspace3;

%%% Zcol/row

%%% row 2

z12=(0, lyc2);
drawdoublerectangle(12, el, hspace4, 1/2);
label.urt(btex Manufacturer etex, z12tl);
x121=x12+sdtbs;
label.rt(btex manuf-name etex, (x121, 3/4[y12bl, y12tl]));

z22=(x12br+hspace1, lyc2);
drawdoublerectangle(22, el, hspace4, 1/2);
label.urt(btex Car-model etex, z22tl);
x221=x22+sdtbs;
label.rt(btex Model-name etex, (x221, 3/4[y12bl, y12tl]));
label.rt(btex Manuf-name (FK) etex, (x221, 1/4[y12bl, y12tl]));

%%% row 1

z21=(x22, lyc1);
drawroundedbox(21, el, hspace2, 2sdtbs)("");
label.urt(btex Car etex, z21tl);
draw z21ml--z21mr;
x211=x21+sdtbs;
label.rt(btex Serial-no etex,       (x211, 5/6[y21bl, y21tl]));
label.rt(btex Manuf-name (FK) etex, (x211, 4/6[y21bl, y21tl]));
label.rt(btex Model-name (FK) etex, (x211, 2/6[y21bl, y21tl]));
label.rt(btex Year etex,            (x211, 1/6[y21bl, y21tl]));

%%%%% relationship lines

%%% MANUFACTURER / CAR-MODEL (12, 22)
drawnormalD(12mr, 22ml);
label.top(btex of etex, 1/2[z12mr, z22ml]);

%%% MANUFACTURER / CAR (12, 21)
VH(12bm, 21ml);
drawnormalthreeD(12bm, 12bm.vh, 21ml);
label.top(btex makes etex, 1/2[z12bm.vh, z21ml]);
label.ulft(btex P{ }  etex, z21ml);

%%% CAR-MODEL / CAR (22, 21)
drawnormalD(22bm, 21tm);
label.lft(btex of etex, 1/2[z21tm,z22bm]);
label.urt(btex { }P etex, z21tm);

%    \end{macrocode}
%
% The end of this diagram
%    \begin{macrocode}
endfig;               % end fig 8

%    \end{macrocode}
%
%
% \subsubsection{Diagram 9: OMT}
%
%    OMT~\cite{RUMBAUGH91} was the precursor to the currently popular UML
% structure modeling language. 
%    If you are curious as to why I believe that lexical languages are in 
% general better than BLA languages, the chapter on developing a compiler
% for OMT highlights, probably unintentionally, some of the disadvantages 
% of BLAs.
%
% The general look of the OMT diagram is almost identical
% to the IDEF1X diagram.
%
%    \begin{macrocode}

beginfig(9)            % example 9  OMT
%%%drawgrid;

el := namespace(btex {\bf MANUFACTURER} etex)(niextra);
eh := onelineh;

hspace1 := namespace(btex made by maker of etex)(4ndextra);

hspace2 := 4onelineh;   % height of CAR
hspace3 := 4onelineh;   % space between rows
hspace4 := 3onelineh;   % height of MANUFACTURER

%%% y coords
lyc1 := 0;
lyc2 := lyc1+hspace2+hspace3;

%%% Zcol/row

%%% row 2

z12=(0, lyc2);
drawdoublerectangle(12, el, hspace4, 1/2);
x121=x12+sdtbs;
label.rt(btex {\bf Manufacturer} etex, (x121, 3/4[y12bl, y12tl]));
label.rt(btex name : String etex,      (x121, 1/4[y12bl, y12tl]));

z22=(x12br+hspace1, lyc2);
drawdoublerectangle(22, el, hspace4, 1/2);
x221=x22+sdtbs;
label.rt(btex {\bf Car Model} etex, (x221, 3/4[y22bl, y22tl]));
label.rt(btex name: String etex,    (x221, 1/4[y22bl, y22tl]));

%%% row 1

z21=(x22, lyc1);
drawdoublerectangle(21, el, hspace2, 1/3);
x211=x21+sdtbs;
label.rt(btex {\bf Car} etex,          (x211, 5/6[y21bl, y21tl]));
label.rt(btex serial-no : String etex, (x211, 4/9[y21bl, y21tl]));
label.rt(btex year : Integer etex,     (x211, 2/9[y21bl, y21tl]));

%%%%% relationship lines

%%% MANUFACTURER / CAR-MODEL (12, 22)
drawnormalD(12mr, 22ml);
label.top(btex {\it makes} etex, 1/2[z12mr, z22ml]);
label.ulft(btex 1+{ } etex, z22ml);

%%% MANUFACTURER / CAR (12, 21)
VH(12bm, 21ml);
drawnormalthreeD(12bm, 12bm.vh, 21ml);
label.top(btex {\it makes} etex, 1/2[z12bm.vh, z21ml]);
label.ulft(btex 1+{ }  etex, z21ml);

%%% CAR-MODEL / CAR (22, 21)
drawnormalD(22bm, 21tm);
label.lft(btex {\it produced as} etex, 1/2[z21tm,z22bm]);

%    \end{macrocode}
%
% The end of this diagram
%    \begin{macrocode}
endfig;               % end fig 9

%    \end{macrocode}
%
%
% \subsubsection{Diagram 10: E-R}
%
%    There are several flavours of Entity-Relationship modeling icons.
% I have used a style from~\cite{ELMASRI89}.
%
%    This example introduces some new icons and \Mpost{} modeling.
%
%    \begin{macrocode}

beginfig(10)            % example 10 E-R
%%%drawgrid;

numeric diam; diam := 2onelineh;

upshift := diam;            % circle diameter
nextup := diam+upshift;

el := namespace(btex MANUFACTURER etex)(niextra);
eh := onelineh;

numeric dl, dh;             % length and height of diamond boxes
dl := 1/2el; dh := 2eh;

numeric marg; marg := 4u;   % double the seperation between parallel lines

hspace1 := 1/2el;

%%% y coords
lyc1 := 0;
lyc2 := lyc1+nextup;
lyc3 := lyc2+nextup;
lyc4 := lyc3+nextup;
lyc5 := lyc4+nextup;

%    \end{macrocode}
%
%    The diagram has 5 rows. Start with the 4th as it is the widest row.
%    \begin{macrocode}
%%% Zcol/row
%%% row 4

z14=(0,lyc4);
drawENT(14, el, eh)(btex manufacturer etex);

z34ml=(x14br+hspace1, y14mr);
drawdiamondbox(34, dl, dh)(btex has etex);

z54ml=(x34mr+hspace1, y34mr);
drawENT(54, el, eh)(btex car\_model etex);

%%% row 5

z15bm=(x14bm, lyc5);
drawcirclebox(15, diam)(btex Name etex);

z55bm=(x54bm, lyc5);
drawcirclebox(55, diam)(btex Name etex);

%    \end{macrocode}
%
%    The third row consists of an ordinary diamond box at the right and
% a doubly enclosed diamond on the left. The |drawtwodiamondbox| routine
% is used for the latter. Note that values of |marg| are
% used to make the oustside of the double diamond larger than the single
% diamonds. 
%    \begin{macrocode}
%%% row 3

z53bm=(x54bm, lyc3);
drawdiamondbox(53, dl, dh)(btex of etex);

z13c=(x14bm, y53c);
drawtwodiamondbox(13, dl+marg, dh+marg, 2/5marg)(btex Makes etex);

%    \end{macrocode}
%
%    The second row just consists of a doubly enclosed rectangular box.
% There is no explicit routine for drawing this, so two |drawENT| routines
% are used for drawing smaller and larger superimposed boxes (one with
% an empty text argument).
%    \begin{macrocode}
%%% row 2

z32bm=(x34bm, lyc2);
drawENT(32, el, eh)(btex car etex);
z31c=z32c;
drawENT(31, el+marg, eh+marg)("");

%%% row 1

z21bm=(x32bl, lyc1);
drawcirclebox(21, 5/4diam)(btex \twolines{Serial}{No} etex);

z41bm=(x32br, lyc1);
drawcirclebox(41, diam)(btex Year etex);

%%%%%% lines

%%% Name / manufacturer (15, 14)
drawnormal(15bm, 14tm);

%%% Name / model (55, 54)
drawnormal(55bm, 54tm);

%%% Mnf / has (14, 34)
drawnormal(14mr, 34ml);
label.top(btex 1 etex, 1/2[z14mr,z34ml]);

%%% has/ model (34, 54)
drawnormal(34mr, 54ml);
label.top(btex N etex, 1/2[z34mr,z54ml]);

%%% Mnf / makes (14, 13)
drawnormal(14bm, 13tm);
label.rt(btex 1 etex, 1/2[z14bm,z13tm]);

%%% model / of (54, 53)
drawnormal(54bm, 53tm);
label.rt(btex 1 etex, 1/2[z54bm,z53tm]);

%    \end{macrocode}
%    In the diagrams so far, except trivially in the first, 
% the lines have all been vertical and/or
% horizontal. Now we meet lines in arbitrary directions, and parallel 
% to boot. 
%
%    A pair of parallel lines joins the bottom of the doubly enclosed diamond
% to the left side of the doubly enclosed rectangle. Drawing one of these is
% simple --- just draw a straight line between the bottom middle of the
% diamond to the middle left of the rectangle.
%    \begin{macrocode}
%%% makes / car (13, 31)
drawnormal(13bm, 31ml);
%    \end{macrocode}
%
%    The point |z31A| is |1/2marg| above the point |z31ml|. This is one end
% of the parallel line.
%    \begin{macrocode}
z31A=(x31ml, y31ml+1/2marg);
%    \end{macrocode}
%
%    The \Mpost{} equation |z1-z2 = frac*(z3-z4)| means that 
% (a) the line |z1--z2| is parallel to the line |z3--z4|, and (b)
% the length of the line |z1--z2| is |frac| of the length of |z3--z4|.
% We next specify that the line |z13U--z31A| is parallel to, and the same
% length as, the line |z13bm--z31ml|;
%    \begin{macrocode}
z13U-z31A = z13bm-z31ml;
%    \end{macrocode}
%
%    The final part of the calculation is to determine the point |z13A| so
% that the line |z31A--z13A| is parallel to our first line and starts
% and ends at the outer perimeters of the boxes (and we already
% know what |z31A| is).
%
% \DescribeVariable{whatever}
%    Remember mediation? A point, |z1234| is on the line |z1--z2| if \\
% |z1234=frac1[z1,z2| holds. \\
% Similarly a point |z1234| is on the line |z3--z4| if \\
% |z1234=frac2[z3,z4]| holds.
%
%    These two equations are linear and provided enough variables are known 
% it is easy, even if tedious and error
% prone, to solve
% for all the unknowns using simple mathematics. Fortunately \Mpost{} has an
% idiom for this kind of calculation using the built-in variable 
% called |whatever|. Each time |whatever| is used it is internally given
% a new name which saves a lot of name inventions on the part of the user.
% The following line of code results in \Mpost{} calculating the intersection
% point, which I call |z13A|, between the two lines |z13U,z31A|, which is
% our parallel lines whose points are known, and the line |z13bm--z13mr|
% which is the lower right line of the outer diamond whose points are known.
%    \begin{macrocode}
z13A = whatever[z13U,z31A] = whatever[z13bm,z13mr];
%    \end{macrocode}
%
%    Finally, draw the second parallel line in the desired position and length.
%    \begin{macrocode}
draw z13A--z31A;
label.urt(btex N etex, 1/2[z13A,z31A]);

%    \end{macrocode}
%
%    Another pair of parallel lines connects the doubly bounded rectangle
% and the singly bounded diamond, and we use a similar calculation as above.
%    \begin{macrocode}
%%% of / car (53, 31)
drawnormal(53bm, 31mr);
z31B=(x31mr, y31mr+1/2marg);
z53U - z31B = z53bm - z31mr;
z53B = whatever[z53U,z31B] = whatever[z53bm,z53ml];
draw z53B--z31B;
label.ulft(btex N etex, 1/2[z53B,z31B]);

%    \end{macrocode}
%
% That's the end of the tricky bits for this diagram.
%    \begin{macrocode}
%%% car / serial no (31, 21)
z31C=(x21tm, y31bl);
drawnormal(31C, 21tm);

%%% car / year (31, 41)
z31D=(x41tm, y31br);
drawnormal(31D, 41tm);

%    \end{macrocode}
%
% The end of this diagram
%    \begin{macrocode}
endfig;               % end fig 10

%    \end{macrocode}
%
%
% \subsubsection{Diagram 11: NIAM}
%
%    Like IDEF1X, NIAM~\cite{NIJSSEN89} is a language for relational database
% structures. In Europe it tends to be preferred to IDEF1X.
%
%    Although the layout and icons of the NIAM illustration differ from 
% the prior
% diagrams, no new techniques are used. The most obvious of the differences
% are the use of oval and circular boxes in place of the rectangular boxes,
% and the use of pairs of rectangular boxes in the middle of the relationship
% lines.
%    \begin{macrocode}

beginfig(11)            % example 11  NIAM
%%%drawgrid;

numeric diam; diam := 2onelineh;    % circle diameter

upshift := diam;
nextup := diam+upshift;

numeric hel, vel;        % length of horizontal and vertical box pairs
eh := onelineh;
hel = namespace(btex made by etex)(nextra);
vel = namespace(btex of prod etex)(nextra);

numeric del, deh;        % horizontal & vertical diameters of oval boxes
del := namespace(btex MANUFACTURER etex)(niextra);
deh := 2eh;

numeric marg; marg := 2u;       % margin for doubly enclosed oval boxes
numeric lmarg; lmarg := marg;   % gap for short lines

numeric dashel, dasheh;         % diameters of dashed ellipses
dashel := del+2marg;
dasheh := deh+2marg;

hspace1 := diam;

%%% y coords
lyc1 := 0;
lyc2 := lyc1+nextup;
lyc3 := lyc2+nextup;

%%% Zcol/row

%%% row 3

x13ml=0; y13bm=lyc3;
drawovalbox(13, del, deh)(btex manufacturer etex);
z14=z13c;
drawdashellipse(14, dashel, dasheh);

z23ml=(x14mr+hspace1, y14mr);
drawENT(23, hel, eh)(btex of etex);

z33bl=z23br;
drawENT(33, hel, eh)(btex made by etex);

z44ml=(x33mr+hspace1, y33mr);
drawdashellipse(44, dashel, dasheh);
z43=z44c;
drawovalbox(43, del, deh)(btex car model etex);

z53ml=(x44mr+hspace1, y44mr);
drawdashcircle(53, diam);
label(btex year etex, z53c);

%%% row 2

z22c=(x23bm,lyc2);
drawcirclebox(22, namespace(btex U etex)(2nextra))(btex U etex);

x42tm=x43bm; y42ml=lyc2;
drawdoublerectangle(42, vel, 2eh, 1/2);
label(btex of etex, z42ct);
label(btex is of etex, z42cb);

%%z52c=(x53x,lyc2);
x52tm=x53bm; y52ml=lyc2;
drawdoublerectangle(52, vel, 2eh, 1/2);
label(btex of prod etex, z52ct);
label(btex prod in etex, z52cb);

%%% row 1

z11ml=(x13ml,lyc1);
drawdashellipse(11, del, deh);
label(btex serial no etex, z11c);

z21ml=(x23ml,lyc1);
drawENT(21, hel, eh)(btex of etex);

z31bl=z21br;
drawENT(31, hel, eh)(btex has etex);

z41c=(x43c,lyc1);
drawcirclebox(41, diam)(btex car etex);

%%%%%% lines

%%% manufacturer / of (14, 23)
drawnormal(14mr, 23ml);

%%% made by / car model (33, 44)
drawnormal(33mr, 44ml);
draw (x33tl, y33tl+lmarg)--(x33tr, y33tl+lmarg);
draw (x33mr, y33mr+lmarg)--(x33mr+eh, y33mr+lmarg);

%%% serial no / of (11, 21)
drawnormal(11mr, 21ml);

%%% of / of (23, 22, 21)
drawnormal(23bm, 22tm); drawnormal(22bm, 21tm);
label.rt(btex id etex, z22mr);

%%% has / car (31, 41)
drawnormal(31mr, 41ml);
draw (x31tl, y31tl+lmarg)--(x31tr, y31tl+lmarg);
draw (x31mr, y31mr+lmarg)--(x33mr+eh, y31mr+lmarg);

%%% model / of (44, 42)
drawnormal(43bm, 42tm);

%%% is of / car (42, 41)
drawnormal(42bm, 41tm);
draw (x42tfr+lmarg, y42tfr)--(x42tfr+lmarg, y42br);
draw (x42bm+lmarg, y42bm)--(x42bm+lmarg, y42bm-eh);

%%% year / of prod (53, 52)
drawnormal(53bm, 52tm);

%%% prod in / car (52, 41)
VH(52bm,41mr);
drawnormalthree(52bm, 52bm.vh, 41mr);
draw (x52tfr+lmarg, y52tfr)--(x52tfr+lmarg, y52br);
draw (x52bm+lmarg, y52bm)--(x52bm+lmarg, y52bm-eh);

%    \end{macrocode}
%
% The end of this diagram
%    \begin{macrocode}
endfig;               % end fig 11

%    \end{macrocode}
%
%    Note that the centers of the boxes on the bottom row are all at |y=0|,
% and hence the bottom halves have negative y values. This does not matter
% as \Mpost{} determines the actual space required for a diagram and does
% not base it on the origin of the coordinate system.
%
%
%    The end of the \Mpost{} examples file.
%    \begin{macrocode}
end

%    \end{macrocode}
%     The end of the example.
%    \begin{macrocode}
%</eg>
%    \end{macrocode}
%
% \subsection{Comments}
%
%    Everyone is likely to have a different style of diagramming. You have
% seen how I do it but that might not be what suits you. Nevertheless,
% the following comments may be of assistance.
%   
%    In my own work I tend to draw a lot of diagrams, using different 
% \file{.mp} files, that have similar sets of `commonly used variables 
% \& values'. Rather than repeating the list in each file, I create a
% \Mpost{} file, called say \file{mycommons.mp}, that includes these 
% and then |input mycommons| after the |input expressg| near the start
% of each diagram file.
%
%    I find it a help to sketch out the diagrams using pencil and paper
% before coding them up. I have to admit, though, that the final results
% often look very different from my initial ideas of the layout.
%
%    You might have noticed that I start the coding at different places
% in the diagrams. Basically I try and plan on getting the boxes aligned
% roughly in rows and/or columns. I then typically start with the longest
% column, or more often with the widest row, and then fill in the rest 
% from there.
%
% \subsection{Running the \Mpost{} example file} \label{sec:run}
%
%    The \file{expeg.mp} file has to be processed by \Mpost{} to obtain
% \EPS{} (\file{eps}) files for viewing or printing. 
% Depending on your installation the command to run \Mpost{} may be
% either: \\
% |mpost expeg| or \\
% |mp expeg| \\
% or perhaps something similar. This will produce eleven files, \file{expeg.1}
% to \file{expeg.11}, each of which is an \file{eps} file for the corresponding
% |beginfig(N)| in \file{expeg.mp}. \Mpost{} defaults to using \TeX{} for
% processing labels which outputs them using Computer Modern
% fonts. Unfortunately \PS{} applications do not understand these so it
% is necessary to get the fonts inserted. This is most simply done by 
% \LaTeX ing a document that includes the \Mpost{} output. A suitable
% file is provided below and is configured to be processed by either
% \LaTeX{} or \pdflatex. Run \LaTeX{} and then dvips (or what you normally
% use to generate printable output) and you will get all eleven diagrams.
%
%
%    \begin{macrocode}
%<*egt>
%    \end{macrocode}
%
%    \begin{macrocode}
%%% expeg.tex    display expressg.dtx MetaPost examples

\documentclass[11pt]{article}
\newif\ifpdf
\ifx\pdfoutput\undefined
  \pdffalse
\else
  \pdftrue
\fi

\ifpdf
  \pdfoutput=1
  \usepackage[pdftex,final]{graphicx}
  \DeclareGraphicsRule{*}{mps}{*}{}
\else
  \usepackage[final]{graphicx}
\fi

%%%% page sizes for ISO document on A4 paper
\setlength{\headheight}{11pt}
\setlength{\headsep}{10mm}
\setlength{\topskip}{11pt}
\setlength{\footskip}{11mm}
\setlength{\textwidth}{160mm}
\setlength{\textheight}{221.5mm}
\setlength{\columnsep}{10mm}
\setlength{\topmargin}{0mm}
\setlength{\oddsidemargin}{0mm}
\setlength{\evensidemargin}{0mm}
\setlength{\marginparwidth}{0pt}
\setlength{\marginparsep}{0pt}
\setlength{\marginparpush}{0pt}
\setlength{\footnotesep}{12pt}
  %%%% for US letterpaper need to change some margins
\setlength{\topmargin}{-9.4mm}
\setlength{\oddsidemargin}{1.55mm}
\setlength{\evensidemargin}{1.55mm}

\begin{document}

\begin{figure}
\centering
  \includegraphics{expeg.1}
\caption{Some boxes and line styles}
\end{figure}

\begin{figure}
\centering
  \includegraphics{expeg.2}
\caption{Example schema level diagram}
\end{figure}

\begin{figure}
\centering
  \includegraphics{expeg.3}
\caption{Example diagram of a tree structure}
\end{figure}

\begin{figure}
\centering
  \includegraphics{expeg.4}
\caption{Supertypes and subtypes}
\end{figure}

\begin{figure}
\centering
  \includegraphics{expeg.5}
\caption{A portion of a large model}
\end{figure}

\begin{figure}
\centering
  \includegraphics{expeg.6}
\caption{Car model using EXPRESS-G}
\end{figure}

\begin{figure}
\centering
  \includegraphics{expeg.7}
\caption{Car model using Shlaer-Mellor}
\end{figure}

\begin{figure}
\centering
  \includegraphics{expeg.8}
\caption{Car model using IDEF1X}
\end{figure}

\begin{figure}
\centering
  \includegraphics{expeg.9}
\caption{Car model using OMT}
\end{figure}

\begin{figure}
\centering
  \includegraphics{expeg.10}
\caption{Car model using E-R}
\end{figure}

\begin{figure}
\centering
  \includegraphics{expeg.11}
\caption{Car model using NIAM}
\end{figure}

\end{document}

%    \end{macrocode}
%
% The end of the \LaTeX{} file.
%    \begin{macrocode}
%</egt>
%    \end{macrocode}
%
% \subsubsection{Using \pdflatex}
%
%    \pdflatex{} generates a \file{.pdf} file directly from \LaTeX{} source
% instead of a \file{.dvi} file. Unfortunately \pdflatex{} does not understand
% \EPS{} in general, but it \emph{does} understand the restricted form
% of \EPS{} generated by \Mpost. By default \pdflatex{} will recognise
% files with an \file{.mps} extension as coming from \Mpost, but \Mpost{}
% generates files with a numeric extension. 
% If you like to use both \Mpost{} and \pdflatex, then it can
% get tedious changing all the numeric extensions to \file{.mps}. The
% following two scripts can help with this. The first is a shell 
% script\footnote{You may well have to modify this to run on your
% operating system.} which calls a Perl script. 
%
% The shell script is called \file{n2mps.sh}. To get suitable versions
% of the example \Mpost{} output files for use with \pdflatex, just do: \\
% |n2mps.sh expeg| \\
% after having run \Mpost{} on \file{expeg.mp}.
%
%    \begin{macrocode}
%<*shell>
#! /bin/sh

#####################################################################
# Shell script n2mps.sh
# Call as: n2mps.sh basename
# List each file basename.* in the directory and run the Perl script
# to copy each basename.N to basenameN.mps, where N is an integer
#
# Copyright 2000, Mauro S. Costa and Peter R. Wilson
#####################################################################

basename=${1:?"A file basename is required."}
extname=N.mps
echo Files $basename.N, where N is a number, will be copied to $basename$extname
for file in `ls $basename.*`
do
 n2mpsprl.prl $file
done

####################### end shell script ###########################

%</shell>
%    \end{macrocode}
% The Perl script, which is called by the \file{n2mps} script:
%    \begin{macrocode}
%<*perl>

#!/usr/local/bin/perl -w

###################################################################
# Perl script: n2mpsprl.prl
# Call as: n2mpsprl.prl filename
# If filename is of the form basename.N, where N is an integer,
# copies file basename.N to file basenameN.mps
#
# Copyright 2000, Mauro S. Costa and Peter R. Wilson
##################################################################

# Test for correct number of input parameters
die "Invalid command line arguments.\nTry $0 <src> \n" if($#ARGV > 1);
die "Invalid command line arguments.\nTry $0 <src> \n" if($#ARGV < 0);

# Assign input file name to variable
$input_file = $ARGV[0];

## test if ends with a number, exit if not
if ($input_file =~ /\w\.\d/) { ; } else { exit; }

# Remove the "dot" from the string variable 
# holding the input file name
$input_file =~ s/\.// ;

# Create a list variable composed of the string variable holding
# the concatenated input file name and the extension ".mps"
@name_list = ($input_file,'.mps') ;

# Join the string variables in the name_list variable into
# a single string variable
$output_file = join("",@name_list) ;

# create a list variable composed to the parameters needed
# for the system copy command excution
@exec_list = ('cp', $ARGV[0], $output_file) ;

# Execute the system copy  ("cp") command
system(@exec_list) ;

############################ end perl script ##########################

%</perl>
%    \end{macrocode}
%
% As an alternative when using \pdflatex{} and the \Lpack{graphicx} package,
% putting \\
% |\DeclareGraphicsRule{*}{mps}{*}{}|    \\
% will cause included graphics files with unknown extensions 
% (e.g., as generated by \Mpost) to be treated as \file{.mps} files.
% \begin{verbatim}
% \documentclass...
% \usepackage{ifpdf}%   you should have this
% \ifpdf
%   \pdfoutput=1
%   \usepackage[pdftex,final]{graphicx}
%   \DeclareGraphicsRule{*}{mps}{*}{}
% \else
%   \usepackage[final]{graphicx}
% \fi
% ...
% \includegraphics{mpfig.23}
% ...
% \end{verbatim}
%
%
% \subsection{Using \LaTeX{} instead of \TeX}
%
%    As already noted, \Mpost{} defaults to using \TeX{} for typesetting
% labels. If you would prefer it to use \LaTeX{} instead, then two things
% have to be done.
% \begin{enumerate}
% \item \Mpost{} looks at the value of an environment variable called |TEX|
%       to see what typesetting system it should use. If the variable is
%       not set, then it uses \TeX. To get it to use \LaTeX{} the environment
%       variable has to be set to |latex|. For example, on the system I use
%       this is done by:
% \begin{verbatim}
% TEX=latex
% export TEX
% \end{verbatim}
%
% \item \LaTeX{} |\documentclass| and |\begin{document}| commands must
%       be put into the |verbatimtex|\ldots|etex| group at the start of
%       the diagramming file. For the example, this might look like
% \begin{verbatim}
% verbatimtex
%   \documentclass{article}
%   % \usepackage{...} % for any packages
%   \def\twolines#1#2{\vbox{\hbox{#1} \hbox{#2}}}
%   \begin{document}
% etex
% \end{verbatim}
%
% \end{enumerate}
%
% \textbf{NOTE:} Both the above are required for \LaTeX. On the other hand,
% if |TEX| is either undefined or has a value other than |tex|, 
% then there must
% be no \LaTeX{} code anywhere in the \file{.mp} file.
%
%    If you need to generate individual self-contained \file{ps} files
% for inclusion in non-\LaTeX{} documents where the font used for labels
% is a member of the Computer Modern family,
% then you need to use LaTeX{} and dvips on \file{*.tex} files that consist
% of only a single diagram and no other text at all. At least on my setup
% I have found it best to run dvips as normal but with output to a file
% instead of a printer. Then use whatever tools are available to you to
% convert the \file{.ps} file to an \file{.eps} one (or at least set the
% correct bounding box values). The primary source on generating and
% using \EPS{} in the \LaTeX{} world is~\cite{RECKDAHL97},
% and~\cite{GOOSSENS97} also has useful information.
%
% \subsection{Using \PS{} fonts}
%
%    \Mpost{} can be made to use \PS{} fonts and, providing the labels
% don't require any special (\TeX) processing, then use of \LaTeX{} may
% be avoided altogether. In order to do this, certain requirements have
% to be put on the content on the \file{.mp} file.
%
% \begin{itemize}
% \item \DescribeVariable{prologues} The 
% diagram file must begin with the line \\
% |prologues:=2;| \\
% which will add a prologue for \PS{} font to the output file.
%
% \item \DescribeVariable{defaultfont} The 
% |defaultfont| must be changed. What it has to be changed
% to depends on the font you want to use. For example, to use the
% Times Roman font, put: \\
% |defaultfont:="ptmr8r";| \\
% just after the |prologues| line.
%
%    For this incantation to work, the file \file{ptmr8r.tfm} must exist
% in a location where \Mpost{} looks for \file{.tfm} files (on the system
% I use it is in directory \texttt{../texmf/fonts/tfm/adobe/times}). Also,
% the file \file{psfonts.map} must include a line like \\
% |ptmr8r  Times-Roman ...| \\
% Again, on my system \file{psfonts.map} is in directory 
% \texttt{../texmf/dvips/misc}.
%
%    I don't know whether or not this works if you don't have a \LaTeX{}
% distribution --- it probably doesn't. But it's unlikely that you don't 
% have one if you
% intend to use \Mpost.
%
% \end{itemize}
%     
%     As a final note on changing fonts, the \Mpost{} |defaultfont| and
% |defaultscale| values only apply to quoted text 
% (e.g., \texttt{"quoted text"}) and not to `btexed' text 
% (e.g., \texttt{btex btexed text etex}). Conversely, \TeX{} or \LaTeX{}
% commands only apply to btexed text and not to quoted text. For more
% details on this, see~\cite{METAFP}.
%    
%
%
%
% \section{The \Mpost{} code} \label{sec:mf}
%
%
%    We start by announcing what it is for.
%
%    \begin{macrocode}
%<*up>
%%% EXPRESSG.MP  MetaPost macros for EXPRESS-G and other BLA diagrams
%%% version 1.5, 31 July 2003
%%% version 1.6, 29 February 2004
%%% version 1.61, 17 March 2004

show "expressg.mp version 1.61, 2004/03/17";

%    \end{macrocode}
%
% \subsection{Variables}
%
% \begin{variable}{u}
%    The unit of length.
%    \begin{macrocode}
newinternal u; numeric u;
u := 1mm;

%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{maxx}
% \begin{variable}{maxy}
%    The maximum x and y coordinates for a diagram.
%    \begin{macrocode}
newinternal maxx, maxy;
numeric maxx, maxy;
maxx := 159.5u;        % smidgeon under 160mm for ISO
maxy := 210u;          % 210mm for ISO

%    \end{macrocode}
% \end{variable}
% \end{variable}
%
% \begin{variable}{defaultdotdiam}
% \begin{variable}{dotdiam}
%    The default and actual diameter of circle and dot line end styles.
%    \begin{macrocode}
newinternal defaultdotdiam, dotdiam;
numeric defaultdotdiam, dotdiam;   
defaultdotdiam := 2u;
dotdiam := defaultdotdiam;

%    \end{macrocode}
% \end{variable}
% \end{variable}
%
% \begin{variable}{normalpensize}
% \begin{variable}{normalpensize}
% \begin{variable}{normalpensize}
% The diameters of the pens for drawing normal, thick and thin lines. (The
% size of the default \Mpost{} pen is 0.5bp).
%    \begin{macrocode}
newinternal normalpensize, thickpensize, thinpensize;
numeric normalpensize, thickpensize, thinpensize;
normalpensize := 0.5bp;
thickpensize  := 1.5bp;
thinpensize   := 0.25bp;
%    \end{macrocode}
% \end{variable}
% \end{variable}
% \end{variable}
%
% \begin{variable}{dotsscale}
% |dotsscale| is the amount the |...pensize| has to be increased so that a 
% dotted line looks as thick as a continuous or dashed line.
%    \begin{macrocode}
newinternal dotsscale; numeric dotsscale;
dotsscale := 2;

%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{normalpen}
% \begin{variable}{thickpen}
% \begin{variable}{thinpen}
% \begin{variable}{dotspen}
% \begin{variable}{dotpen}
%  The pens for drawing lines, plus |dotpen| for drawing a dot line end style.
%    \begin{macrocode}
newinternal normalpen, thickpen, thinpen, dotspen, dotpen;
pen normalpen, thickpen, thinpen, dotspen, dotpen;
normalpen := pencircle scaled normalpensize; % i.e. defaultpen;
thickpen  := pencircle scaled thickpensize;
thinpen   := pencircle scaled thinpensize;
dotspen   := pencircle scaled (dotsscale*normalpensize);
dotpen    := pencircle scaled dotdiam;

%    \end{macrocode}
% \end{variable}
% \end{variable}
% \end{variable}
% \end{variable}
% \end{variable}
%
% \begin{variable}{defaultsmoothrad}
% \begin{variable}{smoothrad}
% The default and initial values for the radius of the arc used for joining
% two lines.
% \changes{v1.3}{2000/05/22}{Added defaultsmoothrad and smoothrad variables}
%    \begin{macrocode}
newinternal defaultsmoothrad;
numeric smoothrad, defaultsmoothrad;
smoothrad := defaultsmoothrad := 2u;

%    \end{macrocode}
% \end{variable}
% \end{variable}
%
% \begin{variable}{defaultdrumlid}
% \begin{variable}{drumlid}
% The default and initial values for the ratio of the minor to major
% diameter of ellipses for the top and bottom of drums.
% \changes{v1.3}{2000/05/22}{Added defaultdrumlid and drumlid variables}
%    \begin{macrocode}
newinternal defaultdrumlid;
numeric drumlid, defaultdrumlid;
drumlid := defaultdrumlid := 0.2;

%    \end{macrocode}
% \end{variable}
% \end{variable}
%
% \begin{variable}{defaultgal}
% \begin{variable}{defaultgab}
% \begin{variable}{defaultgfl}
% \begin{variable}{defaultgfb}
% The default values for the length and base width width of arrowheads and fanins.
%
%    \begin{macrocode}
%%% default length and base width for arrowheads and fanin
newinternal defaultgal, defaultgab, defaultgfl, defaultgfb; 
numeric defaultgal, defaultgab, defaultgfl, defaultgfb; 
defaultgal := defaultgfl := defaultdotdiam;
defaultgab := defaultgfb := defaultgal;

%    \end{macrocode}
% \end{variable}
% \end{variable}
% \end{variable}
% \end{variable}
%
% \begin{variable}{gal}
% \begin{variable}{gab}
% \begin{variable}{gfl}
% \begin{variable}{gfb}
% Values of length and base width of arrowheads and fanins.
%    \begin{macrocode}
%%% length and base width of arrowheads and fanins
newinternal gal, gab, gfl, gfb;  
numeric gal, gab, gfl, gfb;  
gal := defaultgal;
gab := defaultgab;
gfl := defaultgfl;
gfb := defaultgfb;

%    \end{macrocode}
% \end{variable}
% \end{variable}
% \end{variable}
% \end{variable}
%
% \begin{variable}{onelineh}
% The minimum height of a box that encloses a single line of text. 
%
%    \begin{macrocode}
newinternal onelineh;
numeric onelineh;
onelineh := 5u;

%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{sdtbl}
% \begin{variable}{sdtbh}
% \begin{variable}{sdtbs}
% The length, height and inset for a simple data type box. The length is
% sufficient for the name `BOOLEAN' and the height for one line of text.
%    \begin{macrocode}
%%% length, height & inset for simple data type boxes
newinternal sdtbl, sdtbh, sdtbs;
numeric sdtbl, sdtbh, sdtbs; 
sdtbl := 22u; 
sdtbh := onelineh;  
sdtbs := 2u;  

%    \end{macrocode}
% \end{variable}
% \end{variable}
% \end{variable}
%
% \begin{variable}{sdtbel}
% \begin{variable}{sdtbeh}
% \begin{variable}{sdtbes}
% The length, height and inset for a simple EXPRESSION data type box. 
% The length is
% sufficient for the name `EXPRESSION' and the height for one line of text.
%    \begin{macrocode}
%%% length, height & inset for EXPRESSION data type boxes
newinternal sdtbel, sdtbeh, sdtbes; 
numeric sdtbel, sdtbeh, sdtbes; 
sdtbel := 28u;
sdtbeh := sdtbh; sdtbes := sdtbs;

%    \end{macrocode}
% \end{variable}
% \end{variable}
% \end{variable}
%
% \begin{variable}{sdtbgel}
% \begin{variable}{sdtbgeh}
% \begin{variable}{sdtbges}
% The length, height and inset for a simple GENERICENT data type box. 
% The length is
% sufficient for the name `GENERIC\_ENTITY' and the height for one line of text.
% \changes{v1.5}{2003/07/31}{Added sdtbgel, sdtbgeh and sdtbges box lengths}
%    \begin{macrocode}
%%% length, height & inset for GENERICENT data type boxes
newinternal sdtbgel, sdtbgeh, sdtbges; 
numeric sdtbgel, sdtbgeh, sdtbges; 
sdtbgel := 38u;
sdtbgeh := sdtbh; sdtbges := sdtbs;

%    \end{macrocode}
% \end{variable}
% \end{variable}
% \end{variable}
%
% \begin{variable}{pconl}
% The average length of a numeric page connector (e.g., for |9,9 (9,9)|).
%    \begin{macrocode}
%%% average length of numeric page connector
newinternal pconl;
numeric pconl; % length of page connector (for e.g., 9,9 (9,9) )
pconl:=15u;
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{pconh}
% Height of average page connector (one line of text).
%    \begin{macrocode}
%%% height of page connectors (one line)
newinternal pconh;
numeric pconh; 
pconh := onelineh; 

%    \end{macrocode}
% \end{variable}
%
% \begin{variable}{enth}
% \begin{variable}{typeh}
% The height of a one line ENT(ITY) box (|enth|) and the height of a
% one line ENUM(ERATION), SELECT or TYPE box.
%
%    \begin{macrocode}
%%% heights of entity, enum, select, type boxes (One text line)
newinternal enth, typeh;
numeric enth, typeh; 
enth := onelineh;
typeh := onelineh;

%    \end{macrocode}
% \end{variable}
% \end{variable}
%
% \begin{variable}{ish}
% \begin{variable}{isrh}
% The height of a normal one line interschema box (|ish|) and an
% interschema box with one line each for the name and rename (|isrh|).
%    \begin{macrocode}
%%% height of interschema boxes (one text line, no rename), and (name + rename)
newinternal ish, isrh;
numeric ish, isrh;   
ish  := 2onelineh;
isrh := 3onelineh;

%    \end{macrocode}
% \end{variable}
% \end{variable}
%
% \begin{variable}{schemah}
% Height of a one line SCHEMA box.
%    \begin{macrocode}
%%% height of schema boxes (one text line)
newinternal schemah;
numeric schemah; 
schemah := 2onelineh;

%    \end{macrocode}
% \end{variable}
% 
% \begin{variable}{eventh}
% \begin{variable}{eventslope}
% The height (|eventh|) of a one line (G/L)EVENT box and the slope of the 
% sides of a (G/L)EVENT box.
%    \begin{macrocode}
%%% height and slope of event boxes
newinternal eventh, eventslope;
numeric eventh, eventslope; 
eventh := onelineh;
eventslope := 0.25;

%    \end{macrocode}
% \end{variable}
% \end{variable}
%
% \begin{variable}{nextra}
% \begin{variable}{niextra}
% Margins for namespaces in normal (|nextra|) and inset (|niextra|) boxes.
% Inset boxes are the ENUM, SELECT and TYPE boxes.
%    \begin{macrocode}
%%% extra namespaces for boxed names
newinternal nextra, niextra; 
numeric nextra, niextra; 
nextra := 2u;
niextra := nextra+sdtbs;

%    \end{macrocode}
% \end{variable}
% \end{variable}
%
% \begin{variable}{ndextra}
% Margin for namespace on a relationship line.
%    \begin{macrocode}
%%% extra namespace for attribute names
newinternal ndextra;
numeric ndextra;   
ndextra := nextra+dotdiam;

%    \end{macrocode}
% \end{variable}
%
% \subsection{Utility routines}
%
% \begin{routine}{VH}
% \changes{v1.1}{1999/10/30}{Added VH routine}
% Calculates the intersection point |z$vh| between the vertical line through
% |z$| and the horizontal line through |z$$| (see \fref{fig:vhvh}).
%    \begin{macrocode}
%%% calculates mid-point on a path like |_ (vertical, horizontal)
%%% final points are: z$, z$vh, z$$, where z$vh=(x$,y$$)
def VH(suffix $, $$) = 
  z$vh=(x$,y$$); 
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{VhV}
% \changes{v1.1}{1999/10/30}{Added VhV routine}
% Calculates the point |z$vhv| on the vertical line through |z$| and the
% point |z$$vhv| on the vertical line through |z$$|, such that the line
% |z$vhv--z$$vhv| is horizontal and centered vertically between the given
% points (see \fref{fig:vhvh}).
%    \begin{macrocode}
%%% Calculates mid-points on a path like |_ 
%%%                                        |  (vertical, horizontal, vertical)
%%% final points are: z$, z$vhv, z$$vhv, z$$
def VhV(suffix $, $$) =
  y$$vhv=1/2[y$,y$$]; x$$vhv=x$$;
  z$vhv=(x$,y$$vhv);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{HvH}
% \changes{v1.1}{1999/10/30}{Added HvH routine}
% Calculates the point |z$hvh| on the horizontal line through |z$| and the
% point |z$$hvh| on the horizontal line through |z$$|, such that the line
% |z$hvh--z$$hvh| is vertical and centered horizontally between the given
% points (see \fref{fig:vhvh}).
%    \begin{macrocode}
%%% Calculates mid-points on a path like -|_ (horizontal, vertical, horizontal)
%%% final points are: z$, z$hvh, z$$hvh, z$$
def HvH(suffix $, $$) =
  x$hvh=1/2[x$,x$$]; y$hvh=y$;
  z$$hvh=(x$hvh,y$$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{VyV}
% \changes{v1.1}{1999/10/30}{Added VyV routine}
% A generalisation of |VhV|.
% Calculates the point |z$vyv| on the vertical line through |z$| and the
% horizontal line through |y@|, and the point |z$$vyv| on the vertical 
% line through |z$$| and the horizontal line through |y@| (see \fref{fig:vyxh}).
%    \begin{macrocode}
%%% Calculates turning points on a U shaped path (vertical, horizontal, vertical)
%%% final points are: z$, z$vyv, z$$vyv, z$$
def VyV(suffix $, @, $$) =
  z$$vyv=(x$$,y@);
  z$vyv =(x$, y@);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{HxH}
% \changes{v1.1}{1999/10/30}{Added HxH routine}
% A generalisation of |HvH|.
% Calculates the point |z$hxh| on the horizontal line through |z$| and the
% vertical line through |x@|, and the 
% point |z$$hgh| on the horizontal line through |z$$| and the vertical
% line through |x@| (see \fref{fig:vyxh}).
%    \begin{macrocode}
%%% Calculates corner points rotated U shaped path (horizontal, vertical, horizontal)
%%% final points are: z$, z$hxh, z$$hxh, z$$
def HxH(suffix $, @, $$) =
  z$$hxh=(x@,y$$);
  z$hxh =(x@,y$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{namespace}
% |namespace(|\meta{name}|)(|\meta{margin}|)| calculates the length of
% the text string \meta{name} plus the \meta{margin} length. The
% body is enclosed in parentheses\footnote{Requested by Stephan Hennig, 
% \texttt{ctt} thread \textit{[MP, expressg, latexmp] namespace and textext},
% 16 March 2004} 
% so you can do \verb?c=2namespace...?
% \changes{v1.61}{2004/03/17}{Added parentheses to namespace macro}
%    \begin{macrocode}
%%% calculates length taken up by typesetting str, plus margin 
def namespace(text str)(expr margin) =
  (xpart lrcorner(str) - xpart llcorner(str) + margin)
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{dashes}
% Shorthand for a dashed line style. Use as: |draw ... dashes;|.
%    \begin{macrocode}
def dashes = 
  dashed evenly
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{dots}
% Shorthand for a dotted line style. Use as: |draw ... dots;|.
%    \begin{macrocode}
def dots =
  dashed withdots
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{dashedgrid}
% |dashedgrid(|\meta{nx}, \meta{ny}, \meta{dist}|)| draws a thin dashed grid
% with \meta{nx} and \meta{ny} divisions in the $x$ and $y$ directions,
% with \meta{dist} between the grid lines. The grid lines are numbered.
%    \begin{macrocode}
% draw a general dashed grid
def dashedgrid(expr nx, ny, dist) =
  save zg_, zg__, oldpen;
  pair zg_[], zg__[];
  pen oldpen; oldpen = currentpen;
  pickup thinpen;
  for i = 0 upto nx:
    zg_[i] = (i*dist, 0); zg_[i+1000] = (i*dist, ny*dist);
    draw zg_[i]--zg_[i+1000] dashes;
    label.bot(decimal(i), zg_[i]);
  endfor
  for i = 0 upto ny:
    zg__[i] = (0, i*dist); zg__[i+1000] = (nx*dist, i*dist);
    draw zg__[i]--zg__[i+1000] dashes;
    label.lft(decimal(i), zg__[i]);
  endfor
  pickup oldpen;
enddef; 

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawgrid}
% |drawgrid| draws a thin dashed grid filling the permitted space for an
% ISO Standard diagram. The units are in mm and the lines are at 10mm intervals
% with labeling in terms of mm.
%    \begin{macrocode}
%%% draw a 1cm spaced grid of 16(x) by 21(y) cms. (units are mm)
def drawgrid =
  dashedgrid(16, 21, 10mm);
enddef;

%    \end{macrocode}
% \end{routine}
%
% The box drawing routines take as an argument the suffix (|$|) of the 
% left-hand bottom corner point of the box, and normally the length and
% height of the box. 
% The coordinates of the box corners
% are calculated (|z$bl|, |z$br|, |z$tr| and |z$tl|). The midpoints of
% the sides of the box (|z$bm|, |z$mr|, |z$tm|, |z$ml|) are calculated
% as well. The text `center' of the box is |z$c|, while the geometric
% center of the box will be at the intersection point of the lines
% |z$bm--z$tm| and |z$ml--z$mr|. See \fref{fig:boxpoints} for an 
% illustration.
%
% \begin{routine}{rectpoints}
% \changes{v1.1}{1999/10/30}{Added rectpoints routine}
% The routine |rectpoints($, l, h)| calculates
% the corner and midpoints of a rectangular box with bottom left
% at |z$|, length |l| and height |h|. Note that it does \emph{not}
% calculate the center point (see \fref{fig:boxpoints}).
%    \begin{macrocode}
%%% calculates corner and midpoints of a rectangle, 
%%% bottom left at $, length l, height h
def rectpoints(suffix $)(expr l, h) =
  z$bl = z$; 
  z$tr = (x$+l, y$+h);
  z$br = (x$tr, y$bl);
  z$tl = (x$bl, y$tr);
  z$ml = 1/2[z$bl, z$tl];
  z$mr = 1/2[z$br, z$tr];
  z$bm = 1/2[z$bl, z$br];
  z$tm = 1/2[z$tl, z$tr];
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{rhompoints}
% \changes{v1.1}{1999/10/30}{Added rhompoints routine}
% The routine |rhompoints($, l, h, s)| calculates the corner and midpoints
% of a rhomboid length |l|, height |h|, sideslope |s|, and positioned
% with its bottom left hand corner at |z$|. The center point is \emph{not} 
% calculated (see \fref{fig:eventpoints}).
%    \begin{macrocode}
%%% calculate corner, midpoints and center point of a rhomboid.
def rhompoints(suffix $)(expr l, h, s) =
  save eshift;
  numeric eshift; eshift = s*h;
  z$bl = z$;
  z$tr = (x$+l+eshift, y$+h);
  z$br = (x$bl+l, y$bl);
  z$tl = (x$bl+eshift, y$tr);
  z$ml = 1/2[z$bl, z$tl];
  z$mr = 1/2[z$br, z$tr];
  z$bm = (1/2[x$ml,x$mr], y$bl);
  z$tm = (x$bm, y$tr);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{circpoints}
% \changes{v1.1}{1999/10/30}{Added circpoints routine}
% The routine |circpoints($, d)| calculates the `corner' and `midpoints'
% on the circumference of a circle, center |z$| and diameter |d|.
%    \begin{macrocode}
%%% calculate circumferential points on a circle
def circpoints(suffix $)(expr diam) =
  save rad, sinrad, cosrad;
  numeric rad, sinrad, cosrad;
  rad = diam/2;
  sinrad = rad*(sind 45);
  cosrad = rad*(cosd 45);
  z$c=z$;
  z$ml=(x$c-rad, y$c);
  z$mr=(x$c+rad, y$c);
  z$bm=(x$c, y$c-rad);
  z$tm=(x$c, y$c+rad);
  z$tr=(x$c+cosrad, y$c+sinrad);
  z$bl=(x$c-cosrad, y$c-sinrad);
  z$br=(x$tr, y$bl);
  z$tl=(x$bl, y$tr);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \subsection{Path routines}
% \changes{v1.4}{2000/07/10}{Added path routines}
%
% \begin{routine}{~}
% The binary operator |~| is a reimplementation of the METAFONT plain base
% |softjoin| path connector (METAFONTbook, page 266); 
% it connects paths via a small circular arc
% radius |smoothrad|.
%    \begin{macrocode}
%%% circular arc join between two paths
tertiarydef p ~ q =
  begingroup
  c_ := fullcircle scaled 2smoothrad shifted point 0 of q;
  a_ := ypart(c_ intersectiontimes p);
  b_ := ypart(c_ intersectiontimes q);
  if a_ < 0: point 0 of p{direction 0 of p} else: subpath(0,a_) of p fi
    ... if b_ < 0: {direction infinity of q}point infinity of q
        else: subpath(b_,infinity) of q fi
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{sharply}
% |sharply(zi, zj, ...zn)| creates a piecewise linear path through the
% given points. (The code is based on the |flex| routine,
% page 267 of the METAFONTbook).
%    \begin{macrocode}
%%% piecewise linear path between the given points
def sharply(text t) =     % t is a list of pairs
  hide(n_:=0; for z=t: z_[incr n_]:=z; endfor)
  z_1 for k=2 upto n_: --z_[k] endfor
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{smoothly}
% |smoothly(zi, zj, ...zn)| creates a piecewise linear path through the
% given points, with the sharp corners replaced by circular arcs of radius
% |smoothrad|.
% page 267 of the METAFONTbook).
%    \begin{macrocode}
%%% piecewise linear path between the given points with smooth corners
def smoothly(text t) =     % t is a list of pairs
  hide(n_:=0; for z=t: z_[incr n_]:=z; endfor)
  (z_1 for k=2 upto n_-1: --z_[k]) ~ (z_[k] endfor --z_[n_])
enddef;

%    \end{macrocode}
% \end{routine}
%
% \subsection{Line end drawing routines}
%
% \changes{v1.4}{2000/07/10}{Added individual line end drawing routines}
% \begin{routine}{drawO}
% Draw an open circle, diameter |dotdiam| at the end of the vector
% |z$| to |z$$|. Any underlying graphic/text will be hidden.
% All the line end drawing routines have similar code.
%    \begin{macrocode}
%%% Draw an open circle at end of vector from $ to $$ 
def drawO(suffix $, $$) = 
%    \end{macrocode}
% Keep everything inside a group and specify the local variables.
%    \begin{macrocode}
  begingroup
  save v_, c_, l, p;
%    \end{macrocode}
% Specify the types of the local variables.
%    \begin{macrocode}
  pair v_, c_;
  numeric l;
  path p;
%    \end{macrocode}
% |v_| is the difference between the start and end points of the line. 
% That is, it is the vector from the end point to the start point.
%    \begin{macrocode}
  v_ := z$-z$$;
%    \end{macrocode}
% \DescribeRoutine{++}
% \DescribeRoutine{xpart}
% \DescribeRoutine{ypart}
% Using \Mpost's Pythagorean addition operator |++|, where |a++b| means
% $\sqrt{a^{2}+b^{2}}$, we can calculate the length |l| of the line from
% the x and y dimension (|xpart| and |ypart|) of the vector |v_|.
%    \begin{macrocode}
  l := (xpart v_)++(ypart v_);  % length of the line
%    \end{macrocode}
% Using mediation involving the ratio of the circle radius to the length
% of the line, calculate |c_|, the required position of the center of 
% the circle at the end of the line.
%    \begin{macrocode}
  c_ := (dotdiam/(2l))[z$$,z$];
%    \end{macrocode}
% |p| is the path for drawing the circle.
%    \begin{macrocode}
  p := fullcircle scaled dotdiam shifted c_;
%    \end{macrocode}
% Erase anything underneath the circle.
%    \begin{macrocode}
  unfill p;
%    \end{macrocode}
% Now we can draw the circle (twice to make sure it shows).
%    \begin{macrocode}
  draw p; draw p;
%    \end{macrocode}
% Finish the local group and end.
%    \begin{macrocode}
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawD}
% Draw a closed circle, diameter |dotdiam| at the end of the vector
% |z$| to |z$$|. Any underlying graphic/text will be hidden.
%    \begin{macrocode}
%%% Draw a closed circle at end of vector from $ to $$ 
def drawD(suffix $, $$) = 
  begingroup
  save v_, c_, l, p;
  pair v_, c_;
  numeric l;
  path p;
  v_ := z$-z$$;
  l := (xpart v_)++(ypart v_);  % length of the line
  c_ := (dotdiam/(2l))[z$$,z$];
  p := fullcircle scaled dotdiam shifted c_;
  fill p;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawOA}
% Draw an open arrowhead, length |gal| and base width |gab|,
% at the end of the vector from |z$| to |z$$|.
% The same general code pattern is used for non-circular
% line end styles, and is described here. It is not too different
% from drawing circular ends, except that the orientation of the line
% has to be taken into account.
%    \begin{macrocode}
%%% draw an open arrowhead at end of vector from $ to $$
def drawOA(suffix $, $$) =
  begingroup
  save v_, c_, v_u, c_t, c_b, l, hb, p;
  pair v_, c_, v_u, c_t, c_b;
  numeric l, hb;
  path p;
  hb := gab/2;
  v_ := z$-z$$;
  l := (xpart v_)++(ypart v_);  % length of the line
  c_ := (gal/(l))[z$$,z$];      % base of arrowhead
%    \end{macrocode}
% Calculate the unit vector in the direction of the line.
%    \begin{macrocode}
  v_u := unitvector v_;
%    \end{macrocode}
% Calculate one of the corner points on the base of the triangle by
% shifting the midbase point in the direction of the normal to the
% line by half the base width.
%    \begin{macrocode}
  c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
%    \end{macrocode}
% Specify that the other corner point is symmetrically opposite the first.
%    \begin{macrocode}
  c_b - c_ = c_ - c_t;
%    \end{macrocode}
% Draw the triangular arrowhead.
%    \begin{macrocode}
  p = c_b--z$$--c_t--cycle;
  unfill p;
  draw p; draw p;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawCA}
% Draw a closed (black) arrowhead, length |gal| and base width |gab|,
% at the end of the vector from |z$| to |z$$|.
%    \begin{macrocode}
%%% draw a closed arrowhead at end of vector from $ to $$
def drawCA(suffix $, $$) =
  begingroup
  save v_, c_, v_u, c_t, c_b, l, hb, p;
  pair v_, c_, v_u, c_t, c_b;
  numeric l, hb;
  path p;
  hb := gab/2;
  v_ := z$-z$$;
  l := (xpart v_)++(ypart v_);  % length of the line
  c_ := (gal/(l))[z$$,z$];      % base of arrowhead
  v_u := unitvector v_;
  c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
  c_b - c_ = c_ - c_t;
  p = c_b--z$$--c_t--cycle;
  filldraw p;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawA}
% Draw a simple arrowhead, length |gal| and base width |gab|,
% at the end of the vector from |z$| to |z$$|.
%    \begin{macrocode}
%%% draw a simple arrowhead at end of vector from $ to $$
def drawA(suffix $, $$) =
  begingroup
  save v_, c_, v_u, c_t, c_b, l, hb, p;
  pair v_, c_, v_u, c_t, c_b;
  numeric l, hb;
  path p;
  hb := gab/2;
  v_ := z$-z$$;
  l := (xpart v_)++(ypart v_);  % length of the line
  c_ := (gal/(l))[z$$,z$];      % base of arrowhead
  v_u := unitvector v_;
  c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
  c_b - c_ = c_ - c_t;
  p = c_b--z$$--c_t;
  draw p;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawF}
% Draw a fanin, length |gfl| and base width |gfb|,
% at the end of the vector from |z$| to |z$$|.
%    \begin{macrocode}
%%% draws a fanin at the end of the vector from $ to $$
def drawF(suffix $, $$) =
  begingroup
  save v_, c_, v_u, c_t, c_b, l, hb, p;
  pair v_, c_, v_u, c_t, c_b;
  numeric l, hb;
  path p;
  hb := gfb/2;
  v_ := z$-z$$;
  l := (xpart v_)++(ypart v_);  % length of the line
  c_ := (gfl/(l))[z$$,z$];      % apex of fan
  v_u := unitvector v_;
  c_t := z$$ shifted (-hb*(ypart v_u), hb*(xpart v_u));
  c_b - z$$ = z$$ - c_t;
  p = c_b--c_--c_t;
  draw p;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
%
% \subsection{Line drawing routines}
% \changes{v1.4}{2000/07/10}{Stripped in-line line end code from line drawing routines}
%
% \begin{routine}{drawdots}
% Draw a dotted line between the two points |z$| and |z$$|.
%    \begin{macrocode}
%%% Draw a dotted line from $ to $$
def drawdots(suffix $, $$) = 
  pickup dotspen;
  draw z$--z$$ dots; 
  pickup normalpen;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdotsthree}
% Draw a straight dotted line between the three points |z$|, |z@| and |z$$|.
%    \begin{macrocode}
%%% Draws the dotted line $--@--$$
def drawdotsthree(suffix $, @, $$) = 
  pickup dotspen;
  draw z$--z@--z$$ dots; 
  pickup normalpen;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdotsfour}
% Draw a straight dotted line between the four points |z$|, |z@|, |z@@| and |z$$|.
%    \begin{macrocode}
%%% Draw the dotted line $--@--@@--$$
def drawdotsfour(suffix $, @, @@, $$) = 
  pickup dotspen;
  draw z$--z@--z@@--z$$ dots; 
  pickup normalpen;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdotsO}
% Draw a dotted line between the two points |z$| and |z$$|, 
% ending in an open circle, diameter |dotdiam|, at |z$$|. 
%    \begin{macrocode}
%%% Draw a dotted line from $ to $$ with open circle at $$
def drawdotsO(suffix $, $$) = 
  pickup dotspen;
  draw z$--z$$ dots;
  pickup normalpen;
  drawO($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdotsthreeO}
% Draw a straight dotted line between the three points |z$|, |z@| and |z$$|,
% ending in an open circle, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% Draws the dotted line $--@--$$
def drawdotsthreeO(suffix $, @, $$) = 
  pickup dotspen;
  draw z$--z@--z$$ dots; 
  pickup normalpen;
  drawO(@, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdotsfourO}
% Draw a straight dotted line between the four points |z$|, |z@|, |z@@| and |z$$|,
% ending in an open circle, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% Draw the dotted line $--@--@@--$$
def drawdotsfourO(suffix $, @, @@, $$) = 
  pickup dotspen;
  draw z$--z@--z@@--z$$ dots; 
  pickup normalpen;
  drawO(@@, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdotsOO}
% Draw a dotted line between the two points |z$| and |z$$|, 
% ending in open circles, diameter |dotdiam|, at |z$| and |z$$|.
%    \begin{macrocode}
%%% Draw the dotted line from $ to $$, ending in circles diameter dotdiam at $ and $$
def drawdotsOO(suffix $, $$) =
  pickup dotspen;
  draw z$--z$$ dots;
  pickup normalpen;
  drawO($, $$); drawO($$, $);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdash}
% Draw a dashed line between the two points |z$| and |z$$|.
%    \begin{macrocode}
%%% draws a dashed line from $ to $$
def drawdash(suffix $, $$) = 
  draw z$--z$$ dashes; 
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdashthree}
% Draw a straight dashed line between the three points |z$|, |z@| and |z$$|.
%    \begin{macrocode}
%%% draws the dashed line $--@--$$
def drawdashthree(suffix $, @, $$) = 
  draw z$--z@--z$$ dashes; 
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdashfour}
% Draw a straight dashed line between the four points |z$|, |z@|, |z@@| and |z$$|.
%    \begin{macrocode}
%%% draws the dashed line $--@--@@--$$
def drawdashfour(suffix $, @, @@, $$) = 
  draw z$--z@--z@@--z$$ dashes; 
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdashO}
% Draw a dashed line between the two points |z$| and |z$$|, 
% ending in an open circle, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% draws a dashed line from $ to $$, ending in a circle diameter dotdiam at $$
def drawdashO(suffix $, $$) =
  draw z$--z$$ dashes;
  drawO($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdashthreeO}
% Draw a straight dashed line between the three points |z$|, |z@| and |z$$|, 
% ending in an open circle, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% draws the dashed line $--@--$$ with circle at $$
def drawdashthreeO(suffix $, @, $$) =
  draw z$--z@--z$$ dashes;
  drawO(@, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdashfourO}
% Draw a straight dashed line between the four points |z$|, |z@|, |z@@| and |z$$|, 
% ending in an open circle, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% draws the dashed line $--@--@@--$$ with circle at $$
def drawdashfourO(suffix $, @, @@, $$) =
  draw z$--z@--z@@--z$$ dashes;
  drawO(@@, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdashOO}
% Draw a dashed line between the two points |z$| and |z$$|, 
% ending in open circles, diameter |dotdiam|, at |z$| and |z$$|.
%    \begin{macrocode}
% drawdashOO($, $$)
%%% draws a dashed line from $ to $$, ending in circles diameter dotdiam at $ and $$
def drawdashOO(suffix $, $$) =
  draw z$--z$$ dashes;
  drawO($, $$); drawO($$, $);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormal}
% Draw a normal thickness line between the two points |z$| and |z$$|.
%    \begin{macrocode}
%%% draws a normal line from $ to $$.
def drawnormal(suffix $, $$) =
  draw z$--z$$;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalthree}
% Draw a straight normal thickness line between the three points |z$|, |z@| and |z$$|.
%    \begin{macrocode}
% drawnormalthree($, @, $$)
%%% draws the normal line $--@--$$
def drawnormalthree(suffix $, @, $$) = 
  draw z$--z@--z$$; 
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalfour}
% Draw a straight normal thickness line between the four points |z$|, |z@|, |z@@| and |z$$|.
%    \begin{macrocode}
%%% draws the normal line $--@--@@--$$
def drawnormalfour(suffix $, @, @@, $$) = 
  draw z$--z@--z@@--z$$; 
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalO}
% Draw a straight normal thickness line between the two points |z$| and |z$$|, 
% ending in an open circle, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
% drawnormalO($, $$)
%%% draws a normal line from $ to $$, ending in a circle diameter dotdiam at $$
def drawnormalO(suffix $, $$) =
  draw z$--z$$;
  drawO($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalthreeO}
% Draw a straight normal thickness line between the three points |z$|, |z@| and |z$$|, 
% ending in an open circle, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% draws the normal line $--@--$$, ending in a circle at $$
def drawnormalthreeO(suffix $, @, $$) =
  draw z$--z@--z$$;
  drawO(@, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalfourO}
% Draw a straight normal thickness line between the four points |z$|, |z@|, |z@@| and |z$$|, 
% ending in an open circle, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% draws the line $--@--@@--$$, ending in a circle at $$
def drawnormalfourO(suffix $, @, @@, $$) =
  draw z$--z@--z@@--z$$;
  drawO(@@, $$);
enddef;


%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalOO}
% Draw a straight normal thickness line between the two points |z$| and |z$$|, 
% ending in open circles, diameter |dotdiam|, at |z$| and |z$$|.
%    \begin{macrocode}
% drawnormalOO($, $$)
%%% draws a normal line from $ to $$, ending in circles diameter dotdiam at $ and $$
def drawnormalOO(suffix $, $$) =
  draw z$--z$$;
  drawO($, $$); drawO($$, $);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalD}
% Draw a straight normal thickness line between the two points |z$| and |z$$|, 
% ending in a black dot, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% draws a normal line from $ to $$, ending in a dot diameter dotdiam at $$
def drawnormalD(suffix $, $$) =
  draw z$--z$$;
  drawD($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalthreeD}
% Draw a straight normal thickness line between the three points |z$|, |z@| and |z$$|, 
% ending in a black dot, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% draws the normal line $--@--$$, ending in a dot at $$
def drawnormalthreeD(suffix $, @, $$) =
  draw z$--z@--z$$;
  drawD(@, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalfourD}
% Draw a straight normal thickness line between the four points |z$|, |z@|, |z@@| and |z$$|, 
% ending in a black dot, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% draws the normal line $--@--@@--$$, ending in a dot at $$
def drawnormalfourD(suffix $, @, @@, $$) =
  draw z$--z@--z@@--z$$;
  drawD(@@, $$);
enddef;


%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalDD}
% Draw a straight normal thickness line between the two points |z$| and |z$$|, 
% ending in black dots, diameter |dotdiam|, at |z$| and |z$$|.
%    \begin{macrocode}
%%% draws a normal line from $ to $$, ending in dots diameter dotdiam at $ and $$
def drawnormalDD(suffix $, $$) =
  draw z$--z$$;
  drawD($, $$); drawD($$, $);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalOA}
% Draw a straight normal thickness line between the two points |z$| and |z$$|,
% ending with an open arrowhead, length |gal| and base width |gab|,
% at |z$$|. 
%    \begin{macrocode}
%%% draws a normal line from $ to $$, ending with an open arrowhead at $$
def drawnormalOA(suffix $, $$) =
  draw z$--z$$;
  drawOA($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalCA}
% Draw a straight normal thickness line between the two points |z$| and |z$$|,
% ending with a closed (black) arrowhead, length |gal| and base width |gab|,
% at |z$$|.
%    \begin{macrocode}
%%% draws a normal line from $ to $$, ending with a closed arrowhead at $$
def drawnormalCA(suffix $, $$) =
  draw z$--z$$;
  drawCA($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalthreeCA}
% Draw a straight normal thickness line between the three points |z$|, |z@| and |z$$|, 
% ending in a closed arrowhead at |z$$|.
%    \begin{macrocode}
%%% draws the normal line $--@--$$, ending in a black arrowhead at $$
def drawnormalthreeCA(suffix $, @, $$) =
  draw z$--z@--z$$;
  drawCA(@, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalfourCA}
% Draw a straight normal thickness line between the four points |z$|, |z@|, |z@@| and |z$$|, 
% ending in a closed arrowhead at |z$$|.
%    \begin{macrocode}
%%% draws the normal line $--@--@@--$$, ending in a black arrowhead at $$
def drawnormalfourCA(suffix $, @, @@, $$) =
  draw z$--z@--z@@--z$$;
  drawCA(@@, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalF}
% Draw a straight normal thickness line between the two points |z$| and |z$$|,
% ending with a fanin, length |gfl| and base width |gfb|,
% at |z$$|.
%    \begin{macrocode}
%%% draws a normal line from $ to $$, ending with a fanin at $$
def drawnormalF(suffix $, $$) =
  draw z$--z$$;
  drawF($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalFO}
% Draw a straight normal thickness line between the two points |z$| and |z$$|,
% ending with a fanin, length |gfl| and base width |gfb|,
% at |z$| and an open circle, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% draws a normal line from $ to $$, with a fanin at $ and an open circle at $$
def drawnormalFO(suffix $, $$) =
  draw z$--z$$;
  drawO($, $$); drawF($$, $);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawthick}
% Draw a straight thick line between the two points |z$| and |z$$|
%    \begin{macrocode}
%%% draws a thick line from $ to $$.
def drawthick(suffix $, $$) =
  pickup thickpen;
  draw z$--z$$;
  pickup normalpen;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawthickO}
% Draw a straight thick line between the two points |z$| and |z$$|,
% ending with an open circle, diameter |dotdiam|, at |z$$|.
%    \begin{macrocode}
%%% draws a thick line from $ to $$, ending in a circle diameter dotdiam at $$
def drawthickO(suffix $, $$) =
  pickup thickpen;
  draw z$--z$$;
  drawO($, $$);
  pickup normalpen;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawthickOO}
% Draw a straight thick line between the two points |z$| and |z$$|,
% ending with open circles, diameter |dotdiam|, at |z$| and |z$$|.
% \changes{v1.5}{2003/07/31}{Added thickpen to drawthickOO}
%    \begin{macrocode}
%%% draws a thick line from $ to $$, ending in circles diameter dotdiam at $ and $$
def drawthickOO(suffix $, $$) =
  pickup thickpen;
  draw z$--z$$;
  drawO($, $$); drawO($$, $);
  pickup normalpen;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{smooth}
% Rounds the join at |z@| between the two straight lines |z$--z@--z$$|.
% The radius of the circular arc is |smoothrad|. The code employs the
% same technique as used for putting dots, etc., at the end of a line.
% However, in this case we `undraw' the sharp corner before drawing the
% arc.
% \changes{v1.3}{2000/05/22}{Added smooth routine}
%    \begin{macrocode}
%%% replaces the sharp corner on $--@--$$ with a circular arc radius smoothrad
def smooth(suffix $, @, $$) =
  begingroup
  save v_, c_, l, p;
  pair v_, v_', c_, c_';
  path p;
  v_ := z@-z$;
  l := (xpart v_)++(ypart v_);     % length of $--@
  c_ := (smoothrad/l)[z@,z$];      % start of arc on $--@
  v_' := z$$-z@;
  l := (xpart v_')++(ypart v_');   % length of @--$$
  c_' := (smoothrad/l)[z@,z$$];    % end of arc on @--$$
  undraw c_--z@--c_';              % blank original join
  draw c_{v_}..{v_'}c_';           % draw the arc
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{smoothtwo}
% Rounds the joins at |z@| and |z@@| between the three straight lines 
% |z$--z@--z@@--z$$|.
% The radius of the circular arc is |smoothrad|. 
% \changes{v1.3}{2000/05/22}{Added smoothtwo routine}
%    \begin{macrocode}
%%% replaces the sharp corners on $--@--@@--$$ with a circular arc radius smoothrad
def smoothtwo(suffix $, @, @@, $$) =
  smooth($, @, @@); smooth(@, @@, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{smoothdash}
% Rounds the join at |z@| between the two dashed straight lines |z$--z@--z$$|.
% The radius of the circular arc is |smoothrad|. 
% \changes{v1.3}{2000/05/22}{Added smoothdash routine}
%    \begin{macrocode}
%%% replaces the sharp corner on the dashed lines $--@--$$ 
%%% with a circular arc radius smoothrad
def smoothdash(suffix $, @, $$) =
  begingroup
  save v_, c_, l, p;
  pair v_, v_', c_, c_';
  path p;
  v_ := z@-z$;
  l := (xpart v_)++(ypart v_);     % length of $--@
  c_ := (smoothrad/l)[z@,z$];      % start of arc on $--@
  v_' := z$$-z@;
  l := (xpart v_')++(ypart v_');   % length of @--$$
  c_' := (smoothrad/l)[z@,z$$];    % end of arc on @--$$
  undraw c_--z@--c_';              % blank original join
  draw c_{v_}..{v_'}c_' dashes;    % draw the dashed arc
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{smoothdots}
% Rounds the join at |z@| between the two dotted straight lines |z$--z@--z$$|.
% The radius of the circular arc is |smoothrad|. 
% \changes{v1.3}{2000/05/22}{Added smoothdots routine}
%    \begin{macrocode}
%%% replaces the sharp corner on the dotted line $--@--$$ 
%%% with a circular arc radius smoothrad
def smoothdots(suffix $, @, $$) =
  begingroup
  save oldpen;
  pen oldpen; oldpen := currentpen;
  save v_, c_, l, p;
  pair v_, v_', c_, c_';
  path p;
  v_ := z@-z$;
  l := (xpart v_)++(ypart v_);     % length of $--@
  c_ := (smoothrad/l)[z@,z$];      % start of arc on $--@
  v_' := z$$-z@;
  l := (xpart v_')++(ypart v_');   % length of @--$$
  c_' := (smoothrad/l)[z@,z$$];    % end of arc on @--$$
  undraw c_--z@--c_';              % blank original join
  pickup dotspen;
  draw c_{v_}..{v_'}c_' dots;      % draw the dotted arc
  pickup oldpen;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
%
% \subsection{Box drawing routines}
%
% The box drawing routines take as an argument the suffix (|$|) of the 
% left-hand bottom corner point of the box, and normally the length and
% height of the box. There is normally also a text argument that gets
% typeset at the `center' of the box. The coordinates of the box corners
% are calculated (|z$bl|, |z$br|, |z$tr| and |z$tl|). The midpoints of
% the sides of the box (|z$bm|, |z$mr|, |z$tm|, |z$ml|) are calculated
% as well. The text `center' of the box is |z$c|, while the geometric
% center of the box will be at the intersection point of the lines
% |z$bm--z$tm| and |z$ml--z$mr|. See \fref{fig:boxpoints} for an
% illustration.
%
%
% \begin{routine}{drawSCHEMA}
% |drawSCHEMA(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% a SCHEMA box.
%    \begin{macrocode}
%%% draws a schema box, bottom left at $, length l, height h
def drawSCHEMA(suffix $)(expr l, h)(text str) =
  rectpoints($, l, h);
  x$c = 1/2[x$ml, x$mr];
  y$c = 1/2[y$ml, y$tl];
  draw z$bl--z$br--z$tr--z$tl--cycle;  % outer box
  draw z$ml--z$mr;                     % dividing line
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawSDT}
% |drawSDT(|\meta{suffix}|)(|\meta{name}|)| draws
% a simple data type box of length |sdtbl| and height |sdtbh|.
%    \begin{macrocode}
% drawSDT($)(name)
% draw a simple data type box, bottom left at $
def drawSDT(suffix $)(text str) =
  rectpoints($, sdtbl, sdtbh);
  z$ti = (x$tr-sdtbs, y$tr);
  z$bi = (x$ti, y$br);
  z$c = 1/2[z$bl,z$ti];
  draw z$bl--z$br--z$tr--z$tl--cycle;
  draw z$bi--z$ti;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawASDT}
% |drawASDT(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% a simple data type box.
%    \begin{macrocode}
% drawASDT($, l, h)(name)
% draw a simple data type box, bottom left at $, length l, height h
def drawASDT(suffix $)(expr l, h)(text str) =
  rectpoints($, l, h);
  z$ti = (x$tr-sdtbs, y$tr);
  z$bi = (x$ti, y$br);
  z$c = 1/2[z$bl,z$ti];
  draw z$bl--z$br--z$tr--z$tl--cycle;
  draw z$bi--z$ti;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% The |drawNAME(|\meta{suffix}|)| routines draw a simple data type
% box of the given name using the applicable lengths and heights.
% \begin{routine}{drawBINARY}
% \begin{routine}{drawBOOLEAN}
% \begin{routine}{drawCOMPLEX}
% \begin{routine}{drawEXPRESSION}
%    \begin{macrocode}
def drawBINARY(suffix $) =  drawASDT($)(sdtbl, sdtbh)("BINARY"); 
  enddef;
def drawBOOLEAN(suffix $) = drawASDT($)(sdtbl, sdtbh)("BOOLEAN"); 
  enddef;
def drawCOMPLEX(suffix $) = drawASDT($)(sdtbl, sdtbh)("COMPLEX"); 
  enddef;
def drawEXPRESSION(suffix $) = drawASDT($)(sdtbel, sdtbeh)("EXPRESSION"); 
  enddef;
%    \end{macrocode}
% \end{routine}
% \end{routine}
% \end{routine}
% \end{routine}
%
% \begin{routine}{drawGENERIC}
% \begin{routine}{drawINTEGER}
% \begin{routine}{drawLOGICAL}
% \begin{routine}{drawNUMBER}
%    \begin{macrocode}
def drawGENERIC(suffix $) = drawASDT($)(sdtbl, sdtbh)("GENERIC"); 
  enddef;
def drawINTEGER(suffix $) = drawASDT($)(sdtbl, sdtbh)("INTEGER"); 
  enddef;
def drawLOGICAL(suffix $) = drawASDT($)(sdtbl, sdtbh)("LOGICAL"); 
  enddef;
def drawNUMBER(suffix $) =  drawASDT($)(sdtbl, sdtbh)("NUMBER"); 
  enddef;
%    \end{macrocode}
% \end{routine}
% \end{routine}
% \end{routine}
% \end{routine}
%
% \begin{routine}{drawREAL}
% \begin{routine}{drawSTRING}
%    \begin{macrocode}
def drawREAL(suffix $) =    drawASDT($)(sdtbl, sdtbh)("REAL"); 
  enddef;
def drawSTRING(suffix $) =  drawASDT($)(sdtbl, sdtbh)("STRING"); 
  enddef;

%    \end{macrocode}
% \end{routine}
% \end{routine}
%
% \begin{routine}{drawENUM}
% |drawENUM(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% an ENUMERATION type box.
%    \begin{macrocode}
% drawENUM($, l, h)(name)
%%% draw an enumeration type box, bottom left at $, length l, height h
def drawENUM(suffix $)(expr l, h)(text str) =
  rectpoints($, l, h);
  z$ti = (x$tr-sdtbs, y$tr);
  z$bi = (x$ti, y$br);
  z$c = 1/2[z$bl,z$ti];
  draw z$bl--z$br--z$tr--z$tl--cycle dashes;
  draw z$bi--z$ti dashes;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawSELECT}
% |drawSELECT(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% a SELECT type box.
%    \begin{macrocode}
% drawSELECT($, l, h)(name)
%%% draw a select type box, bottom left at $, length l, height h
def drawSELECT(suffix $)(expr l, h)(text str) =
  rectpoints($, l, h);
  z$ti = (x$tl+sdtbs, y$tl);
  z$bi = (x$ti, y$bl);
  z$c = 1/2[z$br,z$ti];
  draw z$bl--z$br--z$tr--z$tl--cycle dashes;
  draw z$bi--z$ti dashes;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawTYPE}
% |drawTYPE(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% a user-defined TYPE type box.
%    \begin{macrocode}
% drawTYPE($, l, h)(name)
%%% draw a simple user defined TYPE box, bottom left at $, length l, height h
def drawTYPE(suffix $)(expr l, h)(text str) =
  rectpoints($, l, h);
  z$c = 1/2[z$bl,z$tr];
  draw z$bl--z$br--z$tr--z$tl--cycle dashes;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawENT}
% |drawENT(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% an ENTITY box.
%    \begin{macrocode}
% drawENT($, l, h)(name)
%%% draw an entity  box, bottom left at $, length l, height h
def drawENT(suffix $)(expr l, h)(text str) =
  rectpoints($, l, h);
  z$c = 1/2[z$bl,z$tr];
  draw z$bl--z$br--z$tr--z$tl--cycle;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawOB}
% |drawOB(|\meta{suffix}, \meta{l}, \meta{h}|)| draws
% a rectangular box with rounded corners (an \ExpressG{} oval box).
%    \begin{macrocode}
% drawOB($, l, h)
% draw an oval box, bottom left at $, length l, height h
def drawOB(suffix $)(expr l, h) =
  save rad;
  numeric rad; rad := h/2;
  rectpoints($, l, h);
  z$cl = 1/2[z$bl, z$tl];
  z$cr = 1/2[z$br, z$tr];
  z$bli = (x$bl+rad, y$bl);
  z$tli = (x$bli, y$tl);
  z$bri = (x$br-rad, y$br);
  z$tri = (x$bri, y$tr);
  z$c = 1/2[z$bl,z$tr];
  draw z$bli--z$bri..z$cr..z$tri--z$tli..z$cl..cycle;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawPREF}
% |drawPREF(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% a page reference oval box.
%    \begin{macrocode}
% drawPREF($, l, h)(name)
%%% draw a page reference box oval, bottom left at $, length l, height h
def drawPREF(suffix $)(expr l, h)(text str) =
  drawOB($, l, h);
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
%
% \begin{routine}{drawISU}
% |drawISU(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% an interschema USE box.
%    \begin{macrocode}
% drawISU($, l, h)(name)
%%% draw an interschema USE box, bottom left at $, length l, height h
def drawISU(suffix $)(expr l, h)(text str) =
  save quarter;
  numeric quarter; quarter := h/4;
  rectpoints($, l, h);
  z$o = (x$, y$+quarter);
  drawOB($o, l, 2quarter);
  z$c = 1/2[z$bl,z$tr];
  label(str, z$c);
  draw z$bl--z$br--z$tr--z$tl--cycle;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawISUR}
% |drawISUR(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)(|\meta{rename}|)| draws
% an interschema USE RENAME box.
% \changes{v1.5}{2003/07/31}{Changed rnm to rname in drawISUR}
%    \begin{macrocode}
% drawISUR($, l, h)(name)(rename)
%%% draw an interschema USE RENAME box, bottom left at $, length l, height h
def drawISUR(suffix $)(expr l, h)(text str, rname) =
  save third;
  numeric third; third := h/3;
  rectpoints($, l, h);
  z$o = (x$, y$+third);
  drawOB($o, l, third);
  z$c = 1/2[z$bl, z$tr];
  label(str, z$c);
  z$rnm = 1/2[z$bl,(x$br,y$br+third)];
  draw z$bl--z$br--z$tr--z$tl--cycle;
  label(rname, z$rnm);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawISR}
% |drawISR(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% an interschema RERERENCE box.
%    \begin{macrocode}
% drawISR($, l, h)(name)
%%% draw an interschema REFERENCE box, bottom left at $, length l, height h
def drawISR(suffix $)(expr l, h)(text str) =
  save quarter;
  numeric quarter; quarter := h/4;
  rectpoints($, l, h);
  z$o = (x$, y$+quarter);
  drawOB($o, l, 2quarter);
  z$c = 1/2[z$bl,z$tr];
  label(str, z$c);
  draw z$bl--z$br--z$tr--z$tl--cycle dashes;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawISRR}
% |drawISRR(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)(|\meta{rename}|)| draws
% an interschema REFERENCE RENAME box.
% \changes{v1.5}{2003/07/31}{Changed rnm to rname in drawISSR} 
%    \begin{macrocode}
% drawISRR($, l, h)(name)(rename)
%%% draw an interschema REFERENCE RENAME box, bottom left at $, length l, height h
def drawISRR(suffix $)(expr l, h)(text str, rname) =
  save third;
  numeric third; third := h/3;
  rectpoints($, l, h);
  z$o = (x$, y$+third);
  drawOB($o, l, third);
  z$c = 1/2[z$bl,z$tr];
  label(str, z$c);
  z$rnm = 1/2[z$bl,(x$br,y$br+third)];
  draw z$bl--z$br--z$tr--z$tl--cycle dashes;
  label(rname, z$rnm);
enddef;

%    \end{macrocode}
% \end{routine}
%
%
% \begin{routine}{drawLEVENT}
% |drawLEVENT(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% a Local EVENT box, with side slope |eventslope|.
%    \begin{macrocode}
% drawLEVENT($, l, h)(name)
%%% draw a Local EVENT box, bottom left at $, length l, height h
def drawLEVENT(suffix $)(expr l, h)(text str) =
  rhompoints($, l, h, eventslope);
  z$c = 1/2[z$ml,z$mr];
  draw z$bl--z$br--z$tr--z$tl--cycle;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawGEVENT}
% |drawGEVENT(|\meta{suffix}, \meta{l}, \meta{h}|)(|\meta{name}|)| draws
% a Global EVENT box, with side slope |eventslope|.
%    \begin{macrocode}
% drawGEVENT($, l, h)(name)
%%% draw a Global EVENT box, bottom left at $, length l, height h
def drawGEVENT(suffix $)(expr l, h)(text str) =
  rhompoints($, l, h, eventslope);
  z$c = 1/2[z$ml,z$mr];
  pickup thickpen;
  draw z$bl--z$br--z$tr--z$tl--cycle;
  pickup normalpen;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
%
%
% \begin{routine}{drawcirclebox}
% |drawcirclebox(|\meta{suffix}, \meta{diam}|)(|\meta{name}|)| draws
% a circle, center |zsuffix| and diameter \meta{diam}, around \meta{name}.
%    \begin{macrocode}
% drawcirclebox($, diam)(name)
%%% draw a circled name, diameter diam centered at $
def drawcirclebox(suffix $)(expr diam)(text str) =
  circpoints($, diam);
  draw z$bl..z$bm..z$br..z$mr..z$tr..z$tm..z$tl..z$ml..cycle;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \subsection{Extra BLA variables and routines}
%
%    Some extra facilities are provided for assistance in drawing 
% non-\ExpressG{} BLA diagrams, such as flow charts, IDEF diagrams
%  or UML structure diagrams.
%
% \begin{variable}{gdl}
% \begin{variable}{gdb}
% |gdl| is the length of a diamond line end style and |gdb| is the base 
% width. 
%    \begin{macrocode}
%%% length and base width of diamond line end styles
newinternal gdl, gdb;
numeric gdl, gdb;
gdl := 2defaultgal;
gdb := 0.75defaultgab;

%    \end{macrocode}
% \end{variable}
% \end{variable}
%
% \begin{routine}{ellipsepoints}
% \changes{v1.2}{1999/11/15}{Added ellipsepoints routine}
% Calculates the points on an ellipse, center at |z$| with horizontal 
% diameter |l| and vertical diameter |h|. It does \emph{not} calculate
% the center point. 
%    \begin{macrocode}
def ellipsepoints(suffix $)(expr l, h) =
  save epp, move;
  path epp;
  pair move;
  z$ml=(x$-l/2, y$); z$mr=(x$ml+l,y$);
  z$tm=(x$, y$+h/2); z$bm=(x$, y$tm-h);
  move = 1/2[z$ml,z$mr];
  epp = fullcircle scaled h xscaled (l/h) shifted move;
  z$tr = point 1.2 of epp;
  z$tl = point 2.8 of epp;
  z$bl = point 5.2 of epp;
  z$br = point 6.8 of epp;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawDCA}
% Draw double closed arrowheads, each length |gal| and base 
% width |gab|, at end of vector from |z$| to |z$$|.
% \changes{v1.4}{2000/07/10}{Added drawDCA}
%    \begin{macrocode}
%%% draws double closed arrowheads at end of vector from $ to $$
def drawDCA(suffix $, $$) =
  begingroup
  save v_, c_, v_u, c_t, c_b, l, hb, p;
  pair v_, c_, v_u, c_t, c_b;
  path p[];
  numeric l, hb;
  hb := gab/2;
  v_ := z$-z$$;
  l := (xpart v_)++(ypart v_);  % length of the line
  c_ := (gal/(l))[z$$,z$];      % base of arrowhead
  v_u := unitvector v_;
  c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
  c_b - c_ = c_ - c_t;
  p1 := c_b--z$$--c_t--cycle;
  filldraw p1;
  p2 := p1 shifted ((xpart c_ - x$$), (ypart c_ - y$$));
  filldraw p2;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawOD}
% Draw an open diamond, length |gdl| and base width |gdb|,
% at end of vector from |z$| to |z$$|.
%    \begin{macrocode}
%%% draws an open diamond at end of vector from $ to $$
def drawOD(suffix $, $$) =
  begingroup
  save v_, c_, c__, v_u, c_t, c_b, l, hb, p;
  pair v_, c_, c__, v_u, c_t, c_b;
  numeric l, hb;
  path p;
  hb := gdb/2;
  v_ := z$-z$$;
  l := (xpart v_)++(ypart v_);  % length of the line
  c_ := (gdl/(2l))[z$$,z$];     % base of diamond
  c__ := (gdl/(l))[z$$,z$];     % interior tip of diamond
  v_u := unitvector v_;
  c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
  c_b - c_ = c_ - c_t;
  p = c_b--z$$--c_t--c__--cycle;
  unfill p;
  draw p; draw p;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawCD}
% Draw a closed diamond, length |gdl| and base width |gdb|,
% at end of vector from |z$| to |z$$|.
%    \begin{macrocode}
%%% draws a closed diamond at end of vector from $ to $$
def drawCD(suffix $, $$) =
  begingroup
  save v_, c_, c__, v_u, c_t, c_b, l, hb, p;
  pair v_, c_, c__, v_u, c_t, c_b;
  numeric l, hb;
  path p;
  hb := gdb/2;
  v_ := z$-z$$;
  l := (xpart v_)++(ypart v_);  % length of the line
  c_ := (gdl/(2l))[z$$,z$];     % base of diamond
  c__ := (gdl/(l))[z$$,z$];     % interior tip of diamond
  v_u := unitvector v_;
  c_t := c_ shifted (-hb*(ypart v_u), hb*(xpart v_u));
  c_b - c_ = c_ - c_t;
  p = c_b--z$$--c_t--c__--cycle;
  filldraw p;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
%
% \begin{routine}{drawdashA}
% Draw a straight dashed line between the two points |z$| and |z$$|,
% ending with an arrowhead, length |gal| and base width |gab|,
% at |z$$|.
%    \begin{macrocode}
%%% draws a dashed line from $ to $$, ending with an arrowhead at $$
def drawdashA(suffix $, $$) =
  draw z$--z$$ dashes;
  drawA($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdashOA}
% Draw a straight dashed line between the two points |z$| and |z$$|,
% ending with an open arrowhead, length |gal| and base width |gab|,
% at |z$$|.
%    \begin{macrocode}
%%% draws a dashed line from $ to $$, ending with an open arrowhead at $$
def drawdashOA(suffix $, $$) =
  draw z$--z$$ dashes;
  drawOA($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalDCA}
% Draw a straight normal line between the two points |z$| and |z$$|,
% ending with double closed arrowheads, each length |gal| and base 
% width |gab|, at |z$$|.
% \changes{v1.2}{1999/11/15}{Added drawnormalDCA}
%    \begin{macrocode}
%%% draws a normal line from $ to $$, ending with double closed arrowheads at $$
def drawnormalDCA(suffix $, $$) =
  draw z$--z$$;
  drawDCA($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalOD}
% Draw a straight normal thickness line between the two points |z$| and |z$$|,
% ending with an open diamond, length |gdl| and base width |gdb|,
% at |z$$|.
%    \begin{macrocode}
%%% draws a normal line from $ to $$, ending with an open diamond at $$
def drawnormalOD(suffix $, $$) =
  draw z$--z$$;
  drawOD($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawnormalCD}
% Draw a straight normal thickness line between the two points |z$| and |z$$|,
% ending with a closed diamond, length |gdl| and base width |gdb|,
% at |z$$|.
%    \begin{macrocode}
%%% draws a normal line from $ to $$, ending with a closed diamond at $$
def drawnormalCD(suffix $, $$) =
  draw z$--z$$;
  drawCD($, $$);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdashcircle}
% \changes{v1.2}{1999/11/15}{Added drawdashcircle}
% Draw a normal thickness dashed open circle, center |z$|, diameter |diam|.
%    \begin{macrocode}
%%% draws an open dashed circle, center z$, diameter diam
def drawdashcircle(suffix $)(expr diam) =
  circpoints($, diam);
  draw z$bl..z$bm..z$br..z$mr..z$tr..z$tm..z$tl..z$ml..cycle dashes;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawcircleA}
% \changes{v1.1}{1999/10/30}{Added drawcircleA routine}
% Draw a normal thickness open circle, center |z$|, diameter |diam|, and with
% a counterclockwise pointing arrow at the topmost point. The arrow has
% length |gal| and base width |gab|.
%    \begin{macrocode}
%%% draws an open circle, center z$, diameter diam, with an arrow at the top
def drawcircleA(suffix $)(expr diam) =
  circpoints($, diam);
  begingroup
  save c_, c_t, c_b, hb;
  pair c_, c_t, c_b;
  numeric hb;
  hb := gab/2;
  c_ := z$tm shifted (gal*right);  % base of arrowhead
  c_t := c_ shifted (hb*up);
  c_b := c_ shifted (hb*down);
  draw z$bl..z$bm..z$br..z$mr..z$tr..z$tm..z$tl..z$ml..cycle;
  draw c_t--z$tm--c_b;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawDot}
% Draw a black dot, center |z$|, diameter |diam|.
% \changes{v1.6}{2004/02/29}{Added drawDot}
%    \begin{macrocode}
%%% draws black dot, center z$, diameter diam
def drawDot(suffix $)(expr diam) =
  begingroup
    save p;
    path p;
    p := fullcircle scaled diam shifted z$;
    filldraw p;
  endgroup
enddef;

%    \nd{macrocode}
% \end{routine}
%
% \begin{routine}{drawCircledDot}
% Draw a black dot, center |z$|, surrounded by a circle, overall 
% diameter |diam|.
% \changes{v1.6}{2004/02/29}{Added drawCircledDot}
%    \begin{macrocode}
%%% draws black dot surrounded by a circle, center z$, diameter diam
def drawCircledDot(suffix $)(expr diam) =
  begingroup
    save l_, p;
    numeric l_;
    path p[];
    l_ := 5/7diam;
    p1 := fullcircle scaled diam shifted z$;
    unfill p1;
    draw p1;
    p2 := fullcircle scaled l_ shifted z$;
    filldraw p2;
  endgroup
enddef;

%    \nd{macrocode}
% \end{routine}
%
%
% \begin{routine}{drawcardbox}
% \changes{v1.1}{1999/10/30}{Added drawcardbox routine}
%  Draw a rectangular box that has its top righthand corner folded down.
% |m| is the height/length of the fold.
%    \begin{macrocode}
def drawcardbox(suffix $)(expr l, h, m)(text str) =
  rectpoints($, l, h);
  begingroup
  save c;
  pair c[];
  c1 = (x$tr-m, y$tr);
  c3 = (x$tr, y$tr-m);
  c2 = (xpart c1, ypart c3);
  draw z$bl--z$br--c3--c1--z$tl--cycle;
  draw c1--c2--c3;
  endgroup;
  z$c = 1/2[z$ml,z$mr];
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdiamondbox}
% Draw a diamond shaped box. Like circles, the box is located at its 
% center point and
% not at the bottom left corner (see \fref{fig:diamondpoints}).
%
%    \begin{macrocode}
def drawdiamondbox(suffix $)(expr l, h)(text str) =
  z$ml=(x$-l/2, y$); z$tm=(x$, y$+h/2);
  z$mr=(x$ml+l, y$); z$bm=(x$, y$tm-h);
  z$bl=1/2[z$ml,z$bm];
  z$br=1/2[z$bm,z$mr];
  z$tr=1/2[z$mr,z$tm];
  z$tl=1/2[z$tm,z$ml];
  z$c=z$;
  draw z$ml--z$bm--z$mr--z$tm--cycle;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawtwodiamondbox}
% \changes{v1.2}{1999/11/15}{Added drawtwodiamondbox routine}
% Draw a diamond shaped box with a smaller diamond inside. 
%
%    \begin{macrocode}
def drawtwodiamondbox(suffix $)(expr l, h, mrg)(text str) =
  z$ml=(x$-l/2, y$); z$tm=(x$, y$+h/2);
  z$mr=(x$ml+l, y$); z$bm=(x$, y$tm-h);
  z$bl=1/2[z$ml,z$bm];
  z$br=1/2[z$bm,z$mr];
  z$tr=1/2[z$mr,z$tm];
  z$tl=1/2[z$tm,z$ml];
  z$c=z$;
  begingroup
  save v_, p, tl, sf;
  pair v_;
  numeric tl, sf;
  path p[];
  p1 = z$ml--z$bm--z$mr--z$tm--cycle;
  draw p1;
  v_ := z$c-z$tr;
  tl := (xpart v_)++(ypart v_);
  sf = 1.0 - mrg/tl;
  p2 = p1 shifted -z$c scaled sf shifted z$c;
  draw p2;
  endgroup;
  label(str, z$c);

enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdoublerectangle}
% Draw a double box where |tf| is the fraction of the height of the 
% top portion. The ends of the dividing line are |z$tfl| and |z$tfr|.
% The text centers are |z$ct| and |z$cb| for the top and bottom portions.
%    \begin{macrocode}
def drawdoublerectangle(suffix $)(expr l, h, tf) =
  rectpoints($, l, h);
  z$tfl=tf[z$tl,z$bl]; z$tfr=tf[z$tr,z$br];
  z$cb=1/2[z$bl,z$tfr];
  z$ct=1/2[z$tfl,z$tr];
  draw z$bl--z$br--z$tr--z$tl--cycle;
  draw z$tfl--z$tfr;
enddef;

%    \end{macrocode}
% \end{routine}
%
%
%
% \begin{routine}{drawtriplerectangle}
% \changes{v1.1}{1999/10/30}{Added drawtriplerectangle routine}
%  Draws a triple box, where |tf| is the fraction of the height for the
% top portion and |bf| is the fraction of the height for the bottom
% portion. Text centers for the three portions are |z$ct|, |z$cm| and |z$cb|
% for the top, middle and bottom portions. The points at the ends of the
% dividing lines are |z$tfl| and |z$tfr| for the top portion
% and |z$bfl| and |z$bfr| for the bottom.
%
%    \begin{macrocode}
def drawtriplerectangle(suffix $)(expr l, h, tf, bf) =
  rectpoints($, l, h);
  z$tfl=tf[z$tl,z$bl]; z$tfr=tf[z$tr,z$br];
  z$bfl=bf[z$bl,z$tl]; z$bfr=bf[z$br,z$tr];
  z$cb=1/2[z$bl,z$bfr];
  z$cm=1/2[z$bfl,z$tfr];
  z$ct=1/2[z$tfl,z$tr];
  draw z$bl--z$br--z$tr--z$tl--cycle;
  draw z$bfl--z$bfr;
  draw z$tfl--z$tfr;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{hiderectangle}
% Draws an invisible rectangular box of the usual dimensions that 
% covers up anything underneath it.
%    \begin{macrocode}
def hiderectangle(suffix $)(expr l, h) =
  begingroup
  save c;
  pair c[];
  c1=(x$,y$);
  c2=c1+(l,0);
  c3=c1+(l,h);
  c4=c1+(0,h);
  unfilldraw c1--c2--c3--c4--cycle;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdashboxover}
% Draws a dashed box that covers up anything underneath it.
%    \begin{macrocode}
def drawdashboxover(suffix $)(expr l, h) =
  rectpoints($, l, h);
  hiderectangle($, l, h);
  z$c = 1/2[z$bl,z$tr];
  draw z$bl--z$br--z$tr--z$tl--cycle dashes;
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawindexbox}
% Draws an index box. The main box is |l| by |h| and the small box
% at the top left is |lp| by |hp|. The main box points are the usual
% |z$bl| etc, but the top box points are |z$P.bl| etc. The |str|
% is put at the center (|z$P.c|) of the small box.
%    \begin{macrocode}
def drawindexbox(suffix $)(expr l, h, lp, hp)(text str) =
  rectpoints($, l, h);
  z$c = 1/2[z$bl,z$tr];
  z$P = z$tl;
  rectpoints($P, lp, hp);
  z$P.c = 1/2[z$P.bl, z$P.tr];
  draw z$bl--z$br--z$tr--z$tl--cycle;
  draw z$P.bl--z$P.br--z$P.tr--z$P.tl--cycle;
  label(str, z$P.c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawroundedbox}
% Draws a rectangular box with rounded corners (like the \LaTeX{} |\oval|).
% The box is |l| by |h| and located by the bottom left corner. The
% corners are rounded with a radius of |r|. If the radius is too large for
% the box it is reduced so that at least two opposite sides are semi-circular.
% The |str| is put at the center (|z$c|) of the box.
%    \begin{macrocode}
def drawroundedbox(suffix $)(expr l, h, r)(text str) =
  rectpoints($, l, h);
  begingroup
  save rad;
  numeric rad; rad := r;
  if rad > l/2:
    rad := l/2;
  fi
  if rad > h/2:
    rad := h/2;
  fi
  draw (x$br-rad, y$br){right}..{up}(x$br, y$br+rad)--
       (x$tr, y$tr-rad){up}..{left}(x$tr-rad, y$tr)--
       (x$tl+rad, y$tl){left}..{down}(x$tl, y$tl-rad)--
       (x$bl, y$bl+rad){down}..{right}(x$bl+rad, y$bl)--cycle;
  endgroup;
  z$c = 1/2[z$bl,z$tr];
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawovalbox}
% \changes{v1.1}{1999/10/30}{Added drawovalbox routine}
% Draws an elliptical box with horizontal diameter |l| and vertical diameter
% |h|. The box is located by the center point.
%    \begin{macrocode}
def drawovalbox(suffix $)(expr l, h)(text str) =
  ellipsepoints($, l, h);
  z$c = 1/2[z$ml,z$mr];
  begingroup
  save p;
  path p;
  p = fullcircle scaled h xscaled (l/h) shifted z$c;
  draw p;
  endgroup;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdashellipse}
% \changes{v1.2}{1999/11/15}{Added drawdashellipse routine}
% Draws a dashed elliptical box with horizontal diameter |l| and vertical diameter
% |h|. The ellipse is located by the center point.
%    \begin{macrocode}
def drawdashellipse(suffix $)(expr l, h) =
  ellipsepoints($, l, h);
  z$c = 1/2[z$ml,z$mr];
  begingroup
  save p;
  path p;
  p = fullcircle scaled h xscaled (l/h) shifted z$c;
  draw p dashes;
  endgroup
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawdrum}
% \changes{v1.3}{2000/05/22}{Added drawdrum routine}
% Draws a drum box with length |l| and height |h|. The top and bottom
% ellipse minor/major diamter ratio id |drumlid|. The text is put at the
% (curved) center of the drum.
%    \begin{macrocode}
def drawdrum(suffix $)(expr l, h)(text str) =
  save vdia; numeric vdia;
  vdia := drumlid*l;                % ellipse vertical diameter
  save pf, ph; path pf, ph;         % full & half ellipse paths

  % points on the basic rectangle
  z$bl = z$;
  z$tr = (x$+l, y$+h);
  z$br = (x$tr, y$);
  z$tl = (x$, y$tr);
  z$ml = 1/2[z$bl,z$tl];
  z$mr = 1/2[z$br,z$tr];
  z$tc = 1/2[z$tl,z$tr];    % center of top rectangle line
  z$bc = 1/2[z$bl,z$br];
  % draw box sides
  draw z$tl--z$bl; draw z$tr--z$br;

  % points on top ellipse
  z$T''' = z$tc;            % ellipse center
  ellipsepoints($T''', l, vdia);
  z$tm  = z$T'''.tm;
  z$tml = z$T'''.tl;
  z$tmr = z$T'''.tr;

  % points on bottom ellipse
  z$B''' = z$bc;
  ellipsepoints($B''', l, vdia);
  z$bm  = z$B'''.bm;
  z$bml = z$B'''.bl;
  z$bmr = z$B'''.br;

  % box center point
  z$c = 1/2[z$T'''.bm, z$B'''.bm];

  % draw top ellipse
  pf = fullcircle scaled vdia xscaled (l/vdia) shifted z$T''';
  draw pf;
  % draw bottom half ellipse
  ph = (halfcircle rotated 180) scaled vdia  xscaled (l/vdia) shifted z$B''';
  draw ph;
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
% \begin{routine}{drawoutputbox}
% Draws an output box. The box is |l| by |h| and the |str|
% is put at the center. The bottom of the box is a wavy line.
%
% This code was supplied by Guy Worthington (see \texttt{comp.text.tex}
% newsgroup thread \textit{Trial, ignore}, January 2004, and in 
% particuar Guy's message of 2004/01/27).
% \changes{v1.6}{2004/02/29}{Added drawoutputbox}
%    \begin{macrocode}
def drawoutputbox(suffix $)(expr l, h)(text str) =
  rectpoints($, l, h);
  begingroup
    save c;
    pair c[];
    c1 = (x$br, y$br+1/8h); % right side of box is shorter
    c2 = (x$bm, y$bm+1/16h);
    % draw the tear
    draw z$bl..c2{dir 45}..c1{dir -15}--z$tr--z$tl--cycle;
  endgroup;
  z$c = (x$bm, 1/2(y$bm+y$tm));
  label(str, z$c);
enddef;

%    \end{macrocode}
% \end{routine}
%
%
% \begin{routine}{drawstickman}
% Draws a full frontal genderless stick figure, inside a rectangle
% |l| by |h|.
% \changes{v1.6}{2004/02/29}{Added drawstickman}
%    \begin{macrocode}
\def drawstickman(suffix $)(expr l, h) =
  rectpoints($,l,h);
  begingroup
    save c;
    pair c[];
    c1 = 8/24[z$bm,z$tm];
    c2 = 15/24[z$bm,z$tm];
    c3 = 18/24[z$bm,z$tm];
    c4 = 1/2[c3,z$tm];
    c6 = (x$bl, ypart(c2));
    c7 = (x$br, ypart(c2));
    draw z$bl--c1--z$br;               % legs
    draw c1--c3;                       % body
    draw c6--c7;                       % arms
    draw c3{right}..z$tm{left}..cycle; % head
  endgroup;
enddef;

%    \end{macrocode}
% \end{routine}
%
%
%
%
% The end of the package
%
%    \begin{macrocode}
%</up>
%    \end{macrocode}
%
%
% \bibliographystyle{alpha}
% \begin{thebibliography}{RBP+91}
%
% \bibitem[EN89]{ELMASRI89}
% R.~Elmasri and S.~B.~Navathe.
% \newblock \emph{Fundamentals of Database Systems}.
% \newblock Benjamin Cummings Publishing Co. Inc., 1989.
%
% \bibitem[GMS94]{GOOSSENS94}
% Michel Goossens, Frank Mittelbach, and Alexander Samarin.
% \newblock \emph{The LaTeX Companion}.
% \newblock Addison-Wesley Publishing Company, 1994.
%
% \bibitem[GRM97]{GOOSSENS97}
% Michel Goossens, Sebastian Rahtz, and Frank Mittelbach.
% \newblock \emph{The LaTeX Graphics Companion}.
% \newblock Addison-Wesley Publishing Company, 1997.
%
% \bibitem[Hob92]{MPOST}
% John D.~Hobby.
% \newblock \emph{A user's manual for MetaPost}.
% \newblock Computing Science Technical Report no. 162, 
%           AT\&T Bell Laboratories, Murray Hill, NJ, April 1992.
%           (Available from CTAN with the MetaPost distribution
%            in \texttt{.../graphics/metapost}).
%
% \bibitem[Hoe98]{HOENIG98}
% Alan Hoenig.
% \newblock \emph{TeX Unbound}.
% \newblock Oxford University Press, 1998.
%
% \bibitem[IDE85]{IDEF1X}
% AFWAL/MLTC, Wright-Patterson AFB, OH.
% \newblock \emph{Integrated Informatiuon Support Systems (IISS), Vol.~V:
%    Common Data Model Subsystem, Part 4: Information Modeling Manual
%    --- IDEF1X}.
% \newblock Report Number: AFWAL--TR--86--4006, Volume~V, 1985.
%
% \bibitem[ISO87]{TR9007}
% ISO TR9007.
% \newblock \emph{Information processing systems ---
%    Concepts and terminology for the conceptual schema and
%    the information base}, 1987.
%
% \bibitem[ISO94]{STEP11}
% ISO 10303-11:1994.
% \newblock \emph{Industrial automation systems and integration ---
%    Product data representation and exchange ---
%    Part~11: Description methods: The EXPRESS language reference manual},
%    1994.
%
% \bibitem[Knu86]{MFONT}
% Donald E~Knuth.
% \newblock \emph{The METAFONTbook}.
% \newblock Addison-Wesley Publishing Company, 1986.
%
% \bibitem[Lam94]{LATEX}
% Leslie Lamport.
% \newblock \emph{\LaTeX: A Document Preperation System}.
% \newblock Second edition. Addison-Wesley Publishing Company, 1994.
%
% \bibitem[NH89]{NIJSSEN89}
% G.~M.~Nijssen and T.~A.~Halpin.
% \newblock \emph{Conceptual Schema and Relational Database Design}.
% \newblock Prentice Hall, 1989.
%
% \bibitem[Rec97]{RECKDAHL97}
% Keith Reckdahl.
% \newblock \emph{Using EPS Graphics in LaTeX2e Documents}.
% \newblock February 1997.
% (Available from CTAN as \texttt{../info/epslatex.ps}).
%
%
% \bibitem[RBP+91]{RUMBAUGH91}
% J.~Rumbaugh, M.~Blaha, W.~Premerlani, F.~Eddy and W.~Lorensen.
% \newblock \emph{Object-Oriented Modeling and Design }
% \newblock Prentice Hall, 1991.
%
% \bibitem[SW94]{EBOOK}
% Douglas A.~Schenck and Peter R.~Wilson.
% \newblock \emph{Information Modeling the EXPRESS Way}.
% \newblock Oxford University Press, 1994.
%           (ISBN 0-19-508714-3)
%
% \bibitem[SM88]{SHLAER88}
% S.~Shlaer and S.~J.~Mellor.
% \newblock \emph{Object-Oriented System Analysis}.
% \newblock Yourdon Press, 1988.
%
% \bibitem[Wil99]{METAFP}
% Peter Wilson.
% \newblock \emph{Some Experiences in Running METAFONT and MetaPost}.
% \newblock November, 1999.
% (Available from CTAN as \texttt{../info/metafp.ps}).
%
% \end{thebibliography}
%
% \textbf{Note:} See \texttt{http://www.tug.org} for information on accessing 
% CTAN --- the Comprehensive \TeX{} Archive Network.
%
%
% \Finale
% \PrintIndex
%
\endinput

%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}