% \iffalse % % permute.dtx and permute.ins and all files generated from these files are % referred to as `the permute package'. It is distributed under the terms % of the \LaTeX\ Project Public License from CTAN archives in directory % macros/latex/base/lppl.txt. Either version 1.0 or, at your option, any % later version. The use of the package is completely free. % % Permission is granted to modify the permute package. You are not allowed to % distribute any changed version of the package, neither under the same name % nor under a different one. % % Send comments, ideas and bug reports via electronic mail to % % cheinz@gmx.de % % (w)(c) 1997--1999 by Carsten Heinz % %<*driver> \documentclass{ltxdoc} \usepackage{permute}[1999/11/10] \EnableCrossrefs \CodelineIndex \OnlyDescription \begin{document} \DocInput{permute.dtx} \end{document} % % \fi % % \newbox\abstractbox % \setbox\abstractbox=\vbox{ % \begin{abstract} % The \textsf{permute} package inputs, outputs and composes permutations. % For example, |$\pmt{(123)}\circ\pmt{(321)} = \pmt{(123)(321)}$| produces % $\pmt{(123)}\circ\pmt{(321)}=\pmt{(123)(321)}$. A misleading example is % $(a\ldots z)\circ(z\ldots a)=\pmt{(a\ldots z)(z\ldots a)}$ printed via % |$(a\ldots z)\circ(z\ldots a)=\pmt{(a\ldots z)(z\ldots a)}$| % --- misleading since the package doesn't care about the human % interpretation of ``\ldots''. % \end{abstract}} % % \title{The \textsf{Permute} Package} % \author{Copyright 1997--1999 by Carsten Heinz} % \date{Version 0.12\\ \box\abstractbox} % \maketitle % %^^A %^^A private adjustments %^^A % \makeatletter % \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}^^A % {1.25ex \@plus1ex \@minus.2ex}^^A % {-1em}^^A % {\normalfont\normalsize\bfseries}} % \makeatother % \newenvironment{syntax}{\list{}{\itemindent-\leftmargin}}{\endlist} % % % \section{User's guide} % % % \subsection{Software license} % % \texttt{permute.dtx} and \texttt{permute.ins} and all files generated from % these files are referred to as `the \textsf{permute} package'. % It is distributed under the terms of the \LaTeX\ Project Public License % from CTAN archives in directory \texttt{macros/latex/base/lppl.txt}. % Either version 1.0 or, at your option, any later version. % The use of the package is completely free. % % Permission is granted to modify the \textsf{permute} package. % You are not allowed to distribute any changed version of the package, % neither under the same name nor under a different one. % % Send comments, ideas and bug reports via electronic mail to % \texttt{cheinz@gmx.de}. % % % \subsection{Installation} % % \begin{enumerate} % \item Following the \TeX\ directory structure (TDS) you should put the files % of the package into directories as follows: % \begin{center} % \begin{tabular}{l@{\quad$\to$\quad}l} % \texttt{permute.dvi} % & \texttt{texmf/doc/latex/permute}\\ % \texttt{permute.dtx}, \texttt{permute.ins} % & \texttt{texmf/source/latex/permute}\\ % \end{tabular} % \end{center} % Of course, you need not to use the TDS. % Simply adjust the directories below. % \item Create the directory \texttt{texmf/tex/latex/permute}. % \item Change the working directory to \texttt{texmf/source/latex/permute} % and run \texttt{permute.ins} through \TeX. % \item Move the generated file to \texttt{texmf/tex/latex/permute} if this % is not already done. % \item If your \TeX\ implementation uses a filename database, update it. % \end{enumerate} % % % \subsection{Input and output formats} % % \paragraph{General notation.} % First we restrict ourselves to $S_1,\ldots,S_9$: % $$S_n:=\{f:\{1,\ldots,n\}\to\{1,\ldots,n\}\,\vert\, % f\textrm{ is one-to-one and onto}\}.$$ % A permutation $f\in S_n$ can be written \textbf{verbose} as an explicit % sequence of pre-image/image pairs like this: % $$f=\pmtv[12\ldots n]{1{f(1)} 2{f(2)} \ldots\ldots n{f(n)}}.$$ % A permutation $\sigma$ is a \textbf{cycle} and written % $\sigma=(x_1x_2\ldots x_k)$ % if and only if there are distinct numbers % $x_1,x_2,\ldots,x_k\in\{1,\ldots,n\}$ % satisfying % \begin{eqnarray*} % \sigma(x_i)&=&x_{i+1}\qquad\textrm{ for all }1\leq i \ProvidesPackage{permute}[1999/11/10 v0.12 (aeio)(cdt)(knm)] % \end{macrocode} % I still wonder whether someone finds out what |(aeio)(cdt)(knm)| means. % \vskip\lineskip % \endgroup % % \begin{macro}{\pmt@iffirst} % \begin{macro}{\pmt@iffound} % \begin{macro}{\pmt@ifsep} % are each controlled by two simple definitions. % \begin{macrocode} \def\pmt@firsttrue{\let\pmt@iffirst\iftrue} \def\pmt@firstfalse{\let\pmt@iffirst\iffalse} % \end{macrocode} % \begin{macrocode} \def\pmt@foundtrue{\let\pmt@iffound\iftrue} \def\pmt@foundfalse{\let\pmt@iffound\iffalse} % \end{macrocode} % \begin{macrocode} \def\pmt@septrue{\let\pmt@ifsep\iftrue} \def\pmt@sepfalse{\let\pmt@ifsep\iffalse} % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % % \subsection{The data format} % % We store a permutation as a list of pre-image/image pairs, but we drop all % with pre-image=image, e.g.\ |{1}{2}{2}{3}{3}{1}| represents (123) no matter % whether considered as element of $S_3$, $S_4$ or $S_6$. % The identity map is represented by an empty macro. % % \begin{macro}{\pmt@GetPreimageOf} % We define the image and get its pre-image from a submacro. |\pmt@firsttrue| % indicates that we are looking for the first of pre-image/image. % \begin{macrocode} \def\pmt@GetPreimageOf#1#2{% \def\pmt@image{#1}\pmt@firsttrue \expandafter\pmt@GIO@#2\relax\relax} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@GetImageOf} % We assign the pre-image, empty |\pmt@gio| (which holds the rest of |#2|), get % the image, and assign the rest of the permutation to |#2|. |\pmt@firstfalse| % indicates that we are looking for the second of pre-image/image. % \begin{macrocode} \def\pmt@GetImageOf#1#2{% \def\pmt@preimage{#1}\let\pmt@gio\@empty \pmt@firstfalse \expandafter\pmt@GIO@#2\relax\relax \let#2\pmt@gio} % \end{macrocode} % Now we iterate down the list. |\pmt@image| or |\pmt@preimage| is used as % temporary macro. If we have found the correct (pre-)image, we can define it % and get the rest of the permutation (up to |\relax\relax|). % \begin{macrocode} \def\pmt@GIO@#1#2{% \pmt@iffirst \def\pmt@preimage{#2}\else \def\pmt@image{#1}\fi \ifx\pmt@image\pmt@preimage \def\pmt@preimage{#1}\def\pmt@image{#2}\pmt@foundtrue \expandafter\pmt@GIO@@ \else % \end{macrocode} % If we haven't found the correct (pre-)image: Image and pre-image must be % equal if we have reached the end of list; otherwise we probably extend % |\pmt@gio| and continue the loop. % \begin{macrocode} \ifx\relax#2% \pmt@foundfalse \pmt@iffirst \let\pmt@preimage\pmt@image \else \let\pmt@image\pmt@preimage \fi \expandafter\@gobbletwo \else \pmt@iffirst\else \pmt@AddTo\pmt@gio{{#1}{#2}}\fi \fi \expandafter\pmt@GIO@ \fi} % \end{macrocode} % The following macro gets the rest of permutation. % \begin{macrocode} \def\pmt@GIO@@#1\relax\relax{% \pmt@iffirst\else \pmt@AddTo\pmt@gio{#1}\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@AddTo} % \begin{macro}{\pmt@Extend} % |\pmt@AddTo| adds |#2| to the contents of the macro |#1|. % |\pmt@Extend| expands the first token of |#2| before doing the same. % \begin{macrocode} \def\pmt@AddTo#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}} \def\pmt@Extend#1#2{% \expandafter\pmt@AddTo\expandafter#1\expandafter{#2}} % \end{macrocode} % \end{macro}\end{macro} % % % \subsection{Whirling things round}\label{iWhirlingThingsRound} % % \begin{macro}{\pmt@Whirl} % Init, whirl, assign. % \begin{macrocode} \def\pmt@Whirl#1#2#3{% \let\pmt@b#2\let\pmt@c#3\let\pmt@a\@empty \pmt@Whirl@ \let#1\pmt@a} % \end{macrocode} % If |\pmt@c| is empty, we only need to append the contents of |\pmt@b| to % |\pmt@a| since |\pmt@c| represents the identity map. % \begin{macrocode} \def\pmt@Whirl@{% \ifx\pmt@c\@empty \pmt@Extend\pmt@a\pmt@b \else % \end{macrocode} % Otherwise we append the first pre-image and its image under the composition, % and continue to check whether |\pmt@c| is empty. % \begin{macrocode} \expandafter\pmt@Whirl@@\pmt@c\relax \expandafter\pmt@Whirl@ \fi} % \end{macrocode} % |\pmt@c| becomes shorter, we get the `composed' image, \ldots % \begin{macrocode} \def\pmt@Whirl@@#1#2#3\relax{% \def\pmt@first{#1}\def\pmt@c{#3}% \pmt@GetImageOf{#2}\pmt@b % \end{macrocode} % and append the new pre-image/image pair if first$\neq$image. % There is only some trouble in making braces around the (pre-)image. % \begin{macrocode} \ifx\pmt@first\pmt@image\else \def\pmt@first{{#1}}% \pmt@Extend\pmt@first{\expandafter{\pmt@image}}% \pmt@Extend\pmt@a\pmt@first \fi} % \end{macrocode} % \end{macro} % % % \subsection{Getting input} % % \begin{macro}{\pmt@InputError} % gives an error message. % \begin{macrocode} \def\pmt@InputError#1{\PackageError{Permute}{#1}\@ehd} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@GetPmt} % We initialize |\pmt@a|, do the conversion and assign the result to |#1|. % \begin{macrocode} \def\pmt@GetPmt#1#2{% \def\pmt@a{#2}% \pmt@foundtrue \pmt@firstfalse \@ifnextchar({\let\pmt@a\@empty \pmt@GetCPmt}% \pmt@GetVPmt #2\relax\relax \let#1\pmt@a} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@GetVPmt} % For the verbose format we only test for an even number of arguments. % \begin{macrocode} \def\pmt@GetVPmt#1#2{% \ifx\relax#2% \ifx\relax#1\else \pmt@InputError{Odd number of tokens}% \let\pmt@a\@empty \fi \else \expandafter\pmt@GetVPmt \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@GetCPmt} % is called |\pmt@GetCPmt|\meta{cycles}|\relax| and |\pmt@a| becomes |\pmt@a| % $\circ$ \meta{cycles}. If we haven't found a right parenthesis and reach the % end of the cycles, we give an error message. Reaching |\relax| we terminate % the loop by gobbling a far away |\pmt@GetCPmt|. % \begin{macrocode} \def\pmt@GetCPmt#1{% \ifx#1\relax \pmt@iffound\else \pmt@InputError{Missing `)'}\fi \expandafter\@gobble \else % \end{macrocode} % If we find a right parenthesis, we either give an error message or use the % first element of the current cycle as image of the last element. In this case % we compose |\pmt@a| and |\pmt@c| via |\pmt@Whirl| defined in section % \ref{iWhirlingThingsRound}. % \begin{macrocode} \ifx#1)% \pmt@iffound \pmt@InputError{Extra `)'}% \else \pmt@iffirst\else \pmt@Extend\pmt@c\pmt@first \pmt@Whirl\pmt@a\pmt@a\pmt@c \fi \pmt@foundtrue \fi \else % \end{macrocode} % A left parenthesis might lead to an error, but in any case initializes two % \texttt{if}s. % \begin{macrocode} \ifx#1(% \pmt@iffound\else \pmt@InputError{Extra `(' or missing `)'}% \fi \pmt@firsttrue \pmt@foundfalse \else % \end{macrocode} % Now we handle all other tokens. If we are outside a cycle (i.e.\ a closing % parenthesis has been found), we give an error message. % \begin{macrocode} \pmt@iffound \pmt@InputError{Missing `('}% \else % \end{macrocode} % Otherwise we initialize or extend |\pmt@c|. % \begin{macrocode} \pmt@iffirst \pmt@firstfalse \def\pmt@first{{#1}}\def\pmt@c{{#1}}% \else \pmt@AddTo\pmt@c{{#1}{#1}}% \fi \fi\fi\fi \fi % \end{macrocode} % Continue the loop (if not gobbled). % \begin{macrocode} \pmt@GetCPmt} % \end{macrocode} % \end{macro} % % % \subsection{Doing output} % % \begin{macro}{\pmt@PrintVPmt} % Is easy. % \begin{macrocode} \def\pmt@PrintVPmt#1{% \let\pmt@a#1\pmt@sepfalse \ensuremath{\pmtldelim \expandafter\pmt@PrintVPmt@\pmt@order\relax \pmtrdelim}} % \end{macrocode} % While |\relax| is not reached, we define pre-image, get the image, and use % |\atop| to typeset the pre-image/image pair. % \begin{macrocode} \def\pmt@PrintVPmt@#1{% \ifx\relax#1\@empty \else \pmt@GetImageOf{#1}\pmt@a \pmt@ifsep \pmt@separator \else \pmt@septrue \fi \mkern1mu% \pmt@ifshort \pmt@image \else{\pmt@preimage\atop\pmt@image}\fi \mkern1mu% \expandafter\pmt@PrintVPmt@ \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmtshorttrue} % \begin{macro}{\pmtshortfalse} % The user accessible \texttt{if} used above. % \begin{macrocode} \def\pmtshorttrue{\let\pmt@ifshort\iftrue} \def\pmtshortfalse{\let\pmt@ifshort\iffalse} \pmtshortfalse % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\pmt@GetFirst} % defines |\pmt@first| and gobbles all tokens up to the next |\relax|. % \begin{macrocode} \def\pmt@GetFirst#1#2\relax{\def\pmt@first{#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@PrintPmt} % We print |\pmtidname| if necessary. % \begin{macrocode} \def\pmt@PrintPmt#1{% \let\pmt@a#1% \ifx\pmt@a\@empty \pmtidname \else \expandafter\pmt@PrintPmt@\pmt@order\relax \fi} % \end{macrocode} % While having an order, we define the first pre-image and print the cycle. % \begin{macrocode} \def\pmt@PrintPmt@#1{% \ifx\relax#1\@empty \expandafter\pmt@PrintPmt@@ \else \def\pmt@first{#1}\pmt@PrintCycle \expandafter\pmt@PrintPmt@ \fi} % \end{macrocode} % Having no order, we print the rest. % \begin{macrocode} \def\pmt@PrintPmt@@{% \ifx\pmt@a\@empty\else \expandafter\pmt@GetFirst\pmt@a\relax \pmt@PrintCycle \expandafter\pmt@PrintPmt@@ \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@PrintCycle} % We print the cycle containing (and beginning with) the contents of % |\pmt@first| if it appears as pre-image. % \begin{macrocode} \def\pmt@PrintCycle{% \expandafter\pmt@GetImageOf\expandafter{\pmt@first}\pmt@a \pmt@iffound (\pmt@preimage\pmt@separator\pmt@image \ifx\pmt@a\@empty\else \pmt@PrintCycle@\pmt@image \fi )% \fi} % \end{macrocode} % While we haven't found the end of the cycle, \ldots % \begin{macrocode} \def\pmt@PrintCycle@#1{% \expandafter\pmt@GetImageOf\expandafter{#1}\pmt@a \ifx\pmt@image\pmt@first\else % \end{macrocode} % we print the image and use the image as new pre-image if permutation is % not empty yet. % \begin{macrocode} \pmt@separator\pmt@image \ifx\pmt@a\@empty \expandafter\@gobblefour \fi \expandafter\pmt@PrintCycle@\expandafter\pmt@image \fi} % \end{macrocode} % \end{macro} % % % \subsection{User commands and parameters} % % \begin{macro}{\pmtidname} % \begin{macro}{\pmtprintorder} % \begin{macro}{\pmtseparator} % \begin{macro}{\pmtldelim} % \begin{macro}{\pmtrdelim} % \begin{macro}{\pmttableborders} % \begin{macro}{\pmtarraystretch} % Some predefined values. % \begin{macrocode} \newcommand*\pmtidname{id} \newcommand*\pmtprintorder{123456789abcdefghi} \newcommand*\pmtseparator{ } \newcommand*\pmtldelim{\left(} \newcommand*\pmtrdelim{\right)} \newcommand*\pmttableborders{lt} \newcommand*\pmtarraystretch{2} % \end{macrocode} % \end{macro}\end{macro}\end{macro}\end{macro} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\pmt@GetPrintArgs} % This helper executes |#1| after getting the optional printing arguments. % \begin{macrocode} \def\pmt@GetPrintArgs#1{% \let\pmt@order\pmtprintorder \def\pmt@next{#1}% \@ifstar{\let\pmt@separator\pmtseparator \pmt@GPA@}% {\let\pmt@separator\@empty \pmt@GPA@}} % \end{macrocode} % If there is no optional argument, we use |\pmtprintorder|, i.e.\ we don't % redefine |\pmt@order|. % \begin{macrocode} \def\pmt@GPA@{\@ifnextchar[\pmt@GPA@@\pmt@next} \def\pmt@GPA@@[#1]{\def\pmt@order{#1}\pmt@next} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt} % \begin{macro}{\pmtv} % \begin{macro}{\pmtprint} % \begin{macro}{\pmtvprint} % The first user commands in terms of known definitions. % \begin{macrocode} \newcommand*\pmt {\pmt@GetPrintArgs{\pmt@\pmt@PrintPmt}} \newcommand*\pmtv{\pmt@GetPrintArgs{\pmt@\pmt@PrintVPmt}} \def\pmt@#1#2{\pmt@GetPmt\pmt@a{#2}#1\pmt@a} % \end{macrocode} % \begin{macrocode} \newcommand*\pmtprint {\pmt@GetPrintArgs{\pmt@PrintPmt\pmt@curr}} \newcommand*\pmtvprint{\pmt@GetPrintArgs{\pmt@PrintVPmt\pmt@curr}} % \end{macrocode} % \end{macro}\end{macro}\end{macro}\end{macro} % % \begin{macro}{\pmt@OptName} % `executes' |#1| with argument |\pmt@curr| \ldots % \begin{macrocode} \def\pmt@OptName#1{\def\pmt@next##1{#1}% \@ifnextchar[\pmt@OptName@{\pmt@next\pmt@curr}} % \end{macrocode} % or |\pmt@s@|\meta{name} if an optional argument is given. |\pmt@LoadPmt| % ensures that the permuation |#1|$=$\meta{name} is defined. % \begin{macrocode} \def\pmt@OptName@[#1]{% \pmt@LoadPmt{#1}\pmt@a \expandafter\pmt@next\csname pmt@s@#1\endcsname} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@LoadPmt} % loads the permutation with name |#1| to |#2|. % \begin{macrocode} \def\pmt@LoadPmt#1#2{% \@ifundefined{pmt@s@#1}% {\expandafter\let\csname pmt@s@#1\endcsname\@empty} \expandafter\let\expandafter#2\csname pmt@s@#1\endcsname} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmtsave} % \begin{macro}{\pmtload} % \begin{macro}{\pmtid} % Some more user commands. % \begin{macrocode} \def\pmtsave#1{\expandafter\let\csname pmt@s@#1\endcsname\pmt@curr} \def\pmtload#1{\pmt@LoadPmt{#1}\pmt@curr} % \end{macrocode} % |##1| $\in$ \{|\pmt@curr|,|\pmt@s@|\meta{name}\} becomes empty. % \begin{macrocode} \newcommand*\pmtid{\pmt@OptName{\let##1\@empty \ignorespaces}} \pmtid % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\pmtdo} % \begin{macro}{\pmtcirc} % The only difference here is the order of |\pmt@a| and |##1|. % \begin{macrocode} \newcommand*\pmtdo{\pmt@OptName{\pmtdo@##1\pmt@a##1}} \newcommand*\pmtcirc{\pmt@OptName{\pmtdo@##1##1\pmt@a}} \def\pmtdo@#1#2#3#4{\pmt@GetPmt\pmt@a{#4}\pmt@Whirl#1#2#3\ignorespaces} % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\pmtimageof} % \begin{macro}{\pmtpreimageof} % We use different arguments to the submacro to get and print the (pre-)image. % \begin{macrocode} \newcommand*\pmtimageof{\pmtimageof@\pmt@GetImageOf\pmt@image} \newcommand*\pmtpreimageof{\pmtimageof@\pmt@GetPreimageOf\pmt@preimage} % \end{macrocode} % \begin{macrocode} \def\pmtimageof@#1#2{% \@ifnextchar[{\pmtimageof@@#1#2}{\pmtimageof@@#1#2[]}} \def\pmtimageof@#1#2[#3]#4{% \ifx\@empty#3\@empty \let\pmt@a\pmt@curr \else \pmt@LoadPmt{#3}\pmt@a \fi #1{#4}\pmt@a #2} % \end{macrocode} % TODO: These two user macros don't behave like |\pmtid|, |\pmtdo|, and so on. % An empty named permutation \meta{name} leads here to \meta{current pmt} and not % to |\pmt@s@|\meta{name}. % \end{macro}\end{macro} % % % \subsection{Making tables} % % \begin{macro}{\pmtvtable} % We use appropriate local redefinitions of |\pmtprint|. % \begin{macrocode} \newcommand*\pmttable {\begingroup \def\pmtprint{\let\pmt@order\pmt@porder\pmt@PrintPmt\pmt@curr}% \pmt@GetPrintArgs\pmt@PrintTable} % \end{macrocode} % \begin{macrocode} \newcommand*\pmtvtable {\begingroup \def\pmtprint{\let\pmt@order\pmt@porder\pmt@PrintVPmt\pmt@curr}% \pmt@GetPrintArgs\pmt@PrintTable} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@PrintTable} % We use macros defined below to indicate the desired borders. % \begin{macrocode} \def\pmt@PrintTable#1#2{% \let\pmt@ifleft\iffalse \pmt@topfalse \expandafter\pmt@SetBorders\pmttableborders\relax % \end{macrocode} % \begin{macrocode} \let\pmt@porder\pmt@order \let\arraystretch\pmtarraystretch % \end{macrocode} % Determine how many columns the table will have, and choose the right % tabular call (according to the desired left border) % \begin{macrocode} \@tempcnta\z@ \pmt@for{\advance\@tempcnta\@ne}{#2}% % \end{macrocode} % Note: It's possible to write |\begin{tabular}{\pmt@ifleft c|\ldots, but the % construction here is independent of that. % \begin{macrocode} \edef\pmt@next{% \noexpand\begin{tabular}{\pmt@ifleft c|\else p{\z@}@{}\fi *{\the\@tempcnta}{@{\ }c@{\ }}}}% \pmt@next % \end{macrocode} % Print the top border if desired. % \begin{macrocode} \pmt@iftop \pmt@ifleft \ensuremath{\circ}\fi \pmt@for{&\pmtid\pmtdo{##1}\pmtprint}{#1}% \\ \hline \fi % \end{macrocode} % And process the rest of the table: we end the previous tabular line (if there % is any), print the left border (if desired) and print one line of the table. % \begin{macrocode} \gdef\pmt@topperms{#2}\pmt@toptrue \pmt@for{% \pmt@iftop \pmt@topfalse \else \expandafter\\\fi \pmt@ifleft \pmtid\pmtdo{##1}\pmtprint \fi \pmt@PrintTableLine{##1}}% {#1}% \end{tabular}\endgroup} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@PrintTableLine} % is |\pmt@PrintTableLine@{#1}|$\langle$\textit{expansion of} % |\pmt@topperms|$\rangle$|,\relax,| % \begin{macrocode} \def\pmt@PrintTableLine#1{% \def\pmt@next{\pmt@PrintTableLine@{#1}}% \expandafter\pmt@next\pmt@topperms,\relax,} % \end{macrocode} % Now we get |#1| and (step by step) each permutation of |\pmt@topperms|, % and print the composition. % \begin{macrocode} \def\pmt@PrintTableLine@#1#2,{% \ifx\relax#2\else \def\pmt@next{&\pmtid\pmtdo{#2}\pmtdo{#1}\pmtprint \pmt@PrintTableLine@{#1}}% \expandafter\pmt@next \fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@for} % performs |#1| for each element of the comma separated list |#2|. % \begin{macrocode} \def\pmt@for#1#2{% \gdef\pmt@for@##1,{% \ifx\relax##1\else \def\pmt@next{#1\expandafter\pmt@for@}% \expandafter\pmt@next \fi}% \pmt@for@#2,\relax,} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmt@SetBorders} % \begin{macro}{\pmt@topfalse} % \begin{macro}{\pmt@toptrue} % \begin{macro}{\pmt@lefttrue} % Get characters up to |\relax| and set \texttt{if}s. % \begin{macrocode} \def\pmt@SetBorders#1{% \ifx\relax#1\else \if l#1\pmt@lefttrue \fi \if t#1\pmt@toptrue \fi \expandafter\pmt@SetBorders \fi} % \end{macrocode} % \begin{macrocode} \def\pmt@topfalse{\global\let\pmt@iftop\iffalse} \def\pmt@toptrue{\global\let\pmt@iftop\iftrue} \def\pmt@lefttrue{\let\pmt@ifleft\iftrue} % \end{macrocode} % \end{macro}\end{macro}\end{macro}\end{macro} % % \begingroup % \begin{macrocode} % % \end{macrocode} % \endgroup % % % \subsection{To do} % % It would be nice to have commands |\pmtpartialtable| and |\pmtvpartialtable| % which print a specified part of a whole table. If requested, these commands % should determine the width of the columns such that the columns are aligned % correctly if all parts are printed and put together. For this procedure it % would be convenient either to store the lists of permutations so that the % commands can access them, or to let the package take control and print the % table on different pages (if necessary). % % Cycle substitution: After |\pmtsubstitute{(123)(45)}{a}| the permutation % (123)(45) is replaced by $a$ in the output. Difficult to implement (due to % \meta{print order} and |\pmtprintorder|) and even more difficult if this % substitution should take place `inside' permutations. % In general, the latter is not possible or not reasonable. % But it is interesting in context with the next ``to do'' paragraph. % % Implement possibility to print (and store) permutations as they have been % entered. % This does not mean just to store the character sequence since composition % with other permutations must be possible, of course. % The internal data format (or an additional list) must represent the input. % Storing an additional \meta{print order} is not sufficient. % For example, (123)(321) is represented by an empty string, but we cannot % recreate it from the empty string and \meta{print order}. % Thus we might need two additional data: \meta{print order} and something % like the original string. % % New command |\pmtinverse|[\oarg{name}] (easy) and its applications. % % % \subsection{History} % % \renewcommand\labelitemi{--} % \begin{itemize} % \item[0.1] from 1997/11/08 (unpublished) % \item commands |\pmt|, |\pmtloadid| (became |\pmtid|), |\pmtdo| (became % |\pmtcirc|), |\pmtprint| and |\pmttable| support $S_1,\ldots,S_9$ % \item[0.11] from 1998/12/17 % \item restriction to $S_1,\ldots,S_9$ dropped % \item new commands |\pmtv|, |\pmtvprint|, |\pmtvtable| provide verbose % printing format and the old commands |\pmt|, |\pmtv|, |\pmtdo|, % |\pmtcirc|, |\pmttable| and |\pmtvtable| now accept verbose input % \item |\pmtprintorder|, |\pmtseparator|, |\pmtidname|, |\pmtldelim|, % |\pmtrdelim|, |\pmttableborders| (prior optional argument), % |\pmtarraystretch| are new parameters % \item[0.12] from 1999/11/10 % \item new commands |\pmtvshorttrue|, |\pmtvshortfalse|, |\pmtsave|, % |\pmtload|, |\pmtimageof| and |\pmtpreimageof| % \item enhanced commands |\pmtid|, |\pmtdo| and |\pmtcirc| % \end{itemize} % % % \Finale % \endinput