%% This is file `kvmacros.tex',
%% Version of January 7th, 2002
%% 
%% Copyright (C) 1998-2002 by Andreas W. Wieland, awwieland@gmx.de 
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License distributed from CTAN
%% archives in directory macros/latex/base/lppl.txt; either
%% version 1 of the License, or (at your option) any later version,
%% with `The Program' referring to the software `kvmacros.tex' and its
%% accompanying documentation and `The Copyright Holder' referring to the
%% person Andreas W. Wieland.
%% 
%% 
%% 
%% IMPORTANT NOTICE: 
%% 
%% For error reports, comments or suggestions in case of UNCHANGED 
%% versions send mail to:
%% awwieland@gmx.de
%% 
%% Anyway, if you use my macros, send me an eMail, too. I would like to know
%% if they are useful to somebody out there.
%%
%% Please do not request updates from me directly. Distribution is 
%% done through Mail-Servers and TeX organizations. 
%% 
%% You are allowed to distribute this file under the condition that 
%% it is distributed together with `kvdoc.tex', `kvdoc.dvi' and `kvdoc.ps'. 
%% 
%% If you receive this file alone from someone, complain! 
%%
\typeout{}
\typeout{Macros for typesetting Karnaugh maps and Veitch charts}
\typeout{Version of January 7th, 2002}
\typeout{by Andreas W. Wieland, awwieland@gmx.de}
\typeout{}
%%
%% Change History:
%% August 04th, 1998: Original Version
%%
%% August 19th, 1998: Minor changes to make the lines within the maps look
%% better, also moved the variable identifiers from the right to the left and
%% added an identifier for the logic function; since then \kvmap has 5
%% instead of 4 parameters. I also included the documentation in an additional
%% Postscript-file.  
%%
%% September 23rd, 1998: Fixed the problem with double braces by introducing
%% the \compdummy and \ende macros in the \ifx-comparisons (see below): 
%% The parameters that are longer than one character do not have to be
%% enclosed in double braces any longer --- single braces are
%% sufficient. However, double braces will still be processed correctly.
%%
%% May 19th, 1999: Changed the documentation (which was months overdue) after
%% F. M. Brown pointed me to the incorrectness of the term
%% "Karnaugh-Veitch-map". Actually, the macros itself haven't
%% changed. Probably I should introduce macros for typesetting Veitch charts
%% as well (which would be a minor task). This version was actually never
%% released. 
%%
%% May 25th, 1999: Introduced macros for Veitch charts
%% (\veitchfoo) and renamed the macros that are solely related to
%% Karnaugh maps from \kvfoo to \karnaughfoo. Introduced aliases for those
%% macros that are user-callable to maintain compatibility with older versions:
%% \kvmap -> \karnaughmap. However, \kvindex, \kvnoindex and \kvunitlength
%% haven't changed their names as they are related to both Karnaugh maps and
%% Veitch charts. Changed the (plain stupid) algorithm that processes the
%% variable-length arguments so that it takes much less time to produce large
%% maps. Several macros so became redundant and are no longer included. Also I
%% introduced \kvindexsize and \kvcontentsize to adjust the font size of the
%% indices and the contents of a diagram. They default to \tiny and
%% \normalsize. 
%%
%% January 17th, 2001: Changed the eMail-address in the macro file and the
%% accompanying documentation and made minor changes to the documentation.
%%
%% January 7th, 2002: Exchanged the \xdef to \gdef in the definition of
%% \kvargumentstring and \kvgetonechar so that things like {\textbf 1} in the
%% argumentlist of \karnaughmap do not cause error messages any longer. 
%% Thanks to Michal Medveck{\'y} for pointing me to this error.
%%
%%
%%
%% We need a fixed dimension for a single field in a Karnaugh map:
%%
\newdimen\kvunitlength
\kvunitlength=8mm
%%
%% We need a default font size for the indices:
%%
\newcommand{\kvindexsize}{\tiny}
%%
%% And we need a default size for the contents and variable identifiers:
%%
\newcommand{\kvcontentsize}{\normalsize}
%%
%% First, we have to introduce some counters:
%%
%% \kvrecursiondepth is used to control the recursion of the
%% \karnaughmakemap- and \veitchmakechart-macro. 
%%
\newcount\kvrecursiondepth
%%
%% The \kvindexcounter is needed for the indices in the fields of the
%% diagrams. 
%%
\newcount\kvindexcounter
%% 
%% \kvxsize and \kvysize store the dimensions of an entire diagram.
%%
\newcount\kvxsize
\newcount\kvysize
%%
%% Some counters are necessary to compute the marks for the variable
%% identifiers:
%%
\newcount\kvvarno
\newcount\kvxvarno
\newcount\kvyvarno
\newcount\kvmarkstart
\newcount\kvmarklength
\newcount\kvmarknum
\newcount\kvmarkmove
%%
%% And we need a savebox to store the variable marks:
%%
\newsavebox\kvsavebox
%%
%% Single fields in a diagram should be indexed, which makes the map easier to
%% use. This is the default. If you don't want indices, simply call
%% \kvnoindex. If you want indices back, call \kvindex:
%%
\def\kvnoindex{%
\def\kvcurrentindex{}}
%%
\def\kvindex{%
\def\kvcurrentindex{%
\the\kvindexcounter\global\advance\kvindexcounter by 1}%
}
%%
\kvindex
%%
%% We need a macro that computes the powers of two:
%%
\def\kvpoweroftwo#1#2{% Computes #1=2^#2, both of which have to be counters
{\ifnum#2>0 
\global\multiply#1 by 2 
\advance#2 by -1
\kvpoweroftwo{#1}{#2}
\fi}}
%%
%% The macros \kvargumentstring, \kvgetchar and \kvgetonechar are needed to
%% process the variabe-length parameters in \karnaughmap and \veitchchart:
%%
\def\kvargumentstring#1{\gdef\kvdummystring{#1{}\noexpand\end}}
%%
\def\kvgetchar{\expandafter\kvgetonechar\kvdummystring}
%%
\def\kvgetonechar#1#2\end{{#1}\gdef\kvdummystring{#2\noexpand\end}}%
%%
%% The Macro \karnaughmakemap calls itself recursively until the parameter #1
%% equals 1, whereupon it returns a single token from the list of arguments,
%% enclosed in a \makebox plus the index (if enabled) in a smaller \makebox:
%%
\def\karnaughmakemap#1#2{{%
\kvrecursiondepth=\number#1
\ifnum\kvrecursiondepth>1
\divide\kvrecursiondepth by 2
\unitlength=\kvunitlength
\multiply\unitlength by \kvrecursiondepth
%%
\ifcase#2
%%
%% The parameter #2 of \karnaughmakemap is needed because the inner Karnaugh
%% maps need to be mirrored. This is achieved by the following case-statement,
%% which orders the inner Karnaugh maps properly:
%%
%% Case 0: top-left Karnaugh map
\begin{picture}(2,2)%
\put(0,1){\karnaughmakemap{\kvrecursiondepth}{0}}%
\put(1,1){\karnaughmakemap{\kvrecursiondepth}{1}}%
\put(0,0){\karnaughmakemap{\kvrecursiondepth}{2}}%
\put(1,0){\karnaughmakemap{\kvrecursiondepth}{3}}%
\end{picture}%
\or
%% Case 1: top-right Karnaugh map
\begin{picture}(2,2)%
\put(1,1){\karnaughmakemap{\kvrecursiondepth}{1}}%
\put(0,1){\karnaughmakemap{\kvrecursiondepth}{0}}%
\put(1,0){\karnaughmakemap{\kvrecursiondepth}{3}}%
\put(0,0){\karnaughmakemap{\kvrecursiondepth}{2}}%
\end{picture}%
\or
%% Case 2: bottom-left Karnaugh map
\begin{picture}(2,2)%
\put(0,0){\karnaughmakemap{\kvrecursiondepth}{2}}%
\put(1,0){\karnaughmakemap{\kvrecursiondepth}{3}}%
\put(0,1){\karnaughmakemap{\kvrecursiondepth}{0}}%
\put(1,1){\karnaughmakemap{\kvrecursiondepth}{1}}%
\end{picture}%
\or
%% Case 3: bottom-right Karnaugh map
\begin{picture}(2,2)%
\put(1,0){\karnaughmakemap{\kvrecursiondepth}{3}}%
\put(0,0){\karnaughmakemap{\kvrecursiondepth}{2}}%
\put(1,1){\karnaughmakemap{\kvrecursiondepth}{1}}%
\put(0,1){\karnaughmakemap{\kvrecursiondepth}{0}}%
\end{picture}%
\fi
\else
\unitlength=\kvunitlength
\begin{picture}(1,1)
\put(0,0){\makebox(1,1){\kvcontentsize\kvgetchar}}%
\put(0.05,0.05){\makebox(0.9,0.9)[bl]{\kvindexsize\kvcurrentindex}}%
\end{picture}
\fi}}%
%%
%% \karnaughmaketopmark typesets the variable marks of a Karnaugh map that are
%% located on top of the diagram:
%%
\def\karnaughmaketopmark{%
  \unitlength\kvunitlength
  \begin{picture}(\kvxsize,1)
    \kvmarkstart=1
    \kvpoweroftwo{\kvmarkstart}{\kvxvarno} % \kvymarkstart is the start 
                                % position for the \multiput
    \kvmarklength=\kvmarkstart 
    \multiply\kvmarklength by 2 % \kvmarklength is the length of a mark
    \kvmarkmove=\kvmarkstart 
    \multiply\kvmarkmove by 4 % This is the move distance for the \multiput.
    \kvmarknum=\kvxsize
    \divide\kvmarknum by \kvmarkmove % This is the number of repetitions for
                                % the \multiput.  
    %The highest-order variable mark needs a special treatment:
    \ifnum\kvmarknum=0\kvmarknum=1\divide\kvmarklength by 2\fi 
    \savebox\kvsavebox(\kvmarklength,1){% 
      \begin{picture}(\kvmarklength,1)
      \put(0,0.3){\makebox(\kvmarklength,0.7){\kvcontentsize\kvgetchar}} 
      \put(0,0.1){\line(0,1){0.4}} 
      \put(\kvmarklength,0.1){\line(0,1){0.4}}
      \put(0,0.3){\line(1,0){\kvmarklength}} 
      \end{picture}}
    \multiput(\kvmarkstart,0)(\kvmarkmove,0){\kvmarknum}{\usebox\kvsavebox}
  \end{picture}
}
%%
%% \karnaughmakeleftmark typesets the variable marks of a Karnaugh map that are
%% located on the left of the diagram:
%%
\def\karnaughmakeleftmark{%
  \unitlength\kvunitlength
  \begin{picture}(-1,\kvysize)(0,-\kvysize)
    \kvmarkstart=1
    \kvpoweroftwo{\kvmarkstart}{\kvyvarno} % \kvmarkstart is the start 
                                % position for the \multiput
    \kvmarklength=\kvmarkstart 
    \multiply\kvmarklength by 2 % \kvmarklength is the length of a mark
    \kvmarkmove=\kvmarkstart 
    \multiply\kvmarkmove by 4 % This now is the move distance for the
                              % \multiput. 
    \kvmarknum=\kvysize
    \divide\kvmarknum by \kvmarkmove % This now is the number of 
                                % repetitions for the \multiput.  
    %The highest-order variable mark needs a special treatment:
    \ifnum\kvmarknum=0\kvmarknum=1\divide\kvmarklength by 2\fi 
    \advance\kvmarkstart by \kvmarklength
    \savebox\kvsavebox(1,\kvmarklength){%
      \begin{picture}(1,\kvmarklength)
        \put(-0.3,0){\makebox(-0.7,\kvmarklength){\kvcontentsize\kvgetchar}}
        \put(-0.1,0){\line(-1,0){0.4}}
        \put(-0.1,\kvmarklength){\line(-1,0){0.4}}
        \put(-0.3,0){\line(0,1){\kvmarklength}}
      \end{picture}}
    \multiput(0,-\kvmarkstart)(0,-\kvmarkmove){\kvmarknum}{\usebox\kvsavebox}
  \end{picture}
}
%% \karnaughmakemarks calls \karnaughmaketopmark or \karnaughmakeleftmark
%% depending on whether \kvvarno is odd or even.
%%
\def\karnaughmakemarks{%
\ifnum\kvvarno>0
  \let\next=\karnaughmakemarks
  \ifodd\kvvarno % We have to make a mark at the top
    \advance\kvxvarno by -1
    \put(0,\kvxvarno){\karnaughmaketopmark}
  \else % We have to make a mark at the left
    \advance\kvyvarno by -1
    \put(-\kvyvarno,-\kvysize){\karnaughmakeleftmark}
  \fi
  \advance\kvvarno by -1
\else
  \let\next=\relax
\fi
\next
}
%%
%% \karnaughmap is the macro that a user calls if he wants to draw a
%% Karnaugh map:  
%%
\def\karnaughmap#1#2#3#4#5{%
%%
%% #1 is the number of variables in the Karnaugh map
%% #2 is the identifier of the function
%% #3 is the list of identifiers of those variables 
%% #4 is the list of tokens that have to be written into the map
%% #5 is something that you want to draw inside the Karnaugh map
%%
\kvvarno=#1  % \kvvarno is the total number of variables 
\kvyvarno=#1 % \kvyvarno is the number of variable marks at the left 
\divide\kvyvarno by 2
\kvxvarno=#1 % \kvxvarno is the number of variable marks on top 
\advance\kvxvarno by -\kvyvarno
\kvxsize=1
\kvpoweroftwo{\kvxsize}{\kvxvarno}
\kvysize=1
\kvpoweroftwo{\kvysize}{\kvyvarno}
\advance\kvxsize by \kvyvarno
\advance\kvxvarno by \kvysize
\unitlength\kvunitlength
\begin{picture}(\kvxsize,\kvxvarno)(-\kvyvarno,-\kvysize)
\advance\kvxsize by -\kvyvarno
\advance\kvxvarno by -\kvysize
\put(0,-\kvysize){%
\begin{picture}(\kvxsize,\kvysize)
\multiput(0,0)(0,1){\kvysize}{\line(1,0){\kvxsize}}
\multiput(0,0)(1,0){\kvxsize}{\line(0,1){\kvysize}}
\put(0,\kvysize){\line(1,0){\kvxsize}}
\put(\kvxsize,0){\line(0,1){\kvysize}}
#5
\end{picture}}
\put(-\kvyvarno,0){\makebox(\kvyvarno,\kvxvarno){#2}}
\kvindexcounter=0
\kvargumentstring{#4}
\put(0,-\kvysize){\karnaughmakemap{\kvysize}{0}}
\ifodd\kvvarno
{\divide\kvxsize by 2
\put(\kvxsize,-\kvysize){\karnaughmakemap{\kvysize}{1}}}
\fi
\kvargumentstring{#3}
\karnaughmakemarks
%%
\end{picture}
}%
%%
%% The definition of \kvmap is necessary to maintain compatibility with older
%% versions of this macro package:
%%
\def\kvmap{\karnaughmap}%
%%
%%
%% The Macro \veitchmakechart calls itself recursively until the parameter #1
%% equals 1, whereupon it returns a single token from the list of arguments,
%% enclosed in a \makebox plus the index (if enabled) in a smaller \makebox:
%%
\def\veitchmakechart#1{{%
\kvrecursiondepth=\number#1
\ifnum\kvrecursiondepth>1
\divide\kvrecursiondepth by 2
\unitlength=\kvunitlength
\multiply\unitlength by \kvrecursiondepth
%%
\begin{picture}(2,2)%
\put(0,1){\veitchmakechart{\kvrecursiondepth}}%
\put(1,1){\veitchmakechart{\kvrecursiondepth}}%
\put(0,0){\veitchmakechart{\kvrecursiondepth}}%
\put(1,0){\veitchmakechart{\kvrecursiondepth}}%
\end{picture}%
\else
\unitlength=\kvunitlength
\begin{picture}(1,1)
\put(0,0){\makebox(1,1){\kvcontentsize\kvgetchar}}%
\put(0.05,0.05){\makebox(0.9,0.9)[bl]{\kvindexsize\kvcurrentindex}}%
\end{picture}
\fi}}%
%%
\def\veitchmaketopmark{%
  \unitlength\kvunitlength
  \begin{picture}(\kvxsize,1)
    \kvmarkstart=1
    \kvpoweroftwo{\kvmarkstart}{\kvxvarno} % \kvymarkstart is the start 
                                % position for the \multiput
    \kvmarklength=\kvmarkstart % \kvmarklength is the length of a mark
    \kvmarkmove=\kvmarkstart 
    \multiply\kvmarkmove by 2 % This is the move distance for the \multiput.
    \kvmarknum=\kvxsize
    \divide\kvmarknum by \kvmarkmove % This is the number of repetitions for
                                     % the \multiput.  
    \savebox\kvsavebox(\kvmarklength,1){% 
      \begin{picture}(\kvmarklength,1)
      \put(0,0.3){\makebox(\kvmarklength,0.7){\kvcontentsize\kvgetchar}} 
      \put(0,0.1){\line(0,1){0.4}} 
      \put(\kvmarklength,0.1){\line(0,1){0.4}}
      \put(0,0.3){\line(1,0){\kvmarklength}} 
      \end{picture}}
    \multiput(\kvmarkstart,0)(\kvmarkmove,0){\kvmarknum}{\usebox\kvsavebox}
  \end{picture}
}
%%
\def\veitchmakeleftmark{%
  \unitlength\kvunitlength
  \begin{picture}(-1,\kvysize)(0,-\kvysize)
    \kvmarkstart=1
    \kvpoweroftwo{\kvmarkstart}{\kvyvarno} % \kvmarkstart is the start 
                                % position for the \multiput
    \kvmarklength=\kvmarkstart 
    \kvmarkmove=\kvmarkstart 
    \multiply\kvmarkmove by 2 % This now is the move distance for the \multiput. 
    \kvmarknum=\kvysize
    \divide\kvmarknum by \kvmarkmove % This now is the number of 
                                     % repetitions for the \multiput.  
    \advance\kvmarkstart by \kvmarklength
    \savebox\kvsavebox(1,\kvmarklength){%
      \begin{picture}(1,\kvmarklength)
        \put(-0.3,0){\makebox(-0.7,\kvmarklength){\kvcontentsize\kvgetchar}}
        \put(-0.1,0){\line(-1,0){0.4}}
        \put(-0.1,\kvmarklength){\line(-1,0){0.4}}
        \put(-0.3,0){\line(0,1){\kvmarklength}}
      \end{picture}}
    \multiput(0,-\kvmarkstart)(0,-\kvmarkmove){\kvmarknum}{\usebox\kvsavebox}
  \end{picture}
}
%%
\def\veitchmakemarks{%
\ifnum\kvvarno>0
  \let\next=\veitchmakemarks
  \ifodd\kvvarno % We have to make a mark at the top
    \advance\kvxvarno by -1
    \put(0,\kvxvarno){\veitchmaketopmark}
  \else % We have to make a mark at the left
    \advance\kvyvarno by -1
    \put(-\kvyvarno,-\kvysize){\veitchmakeleftmark}
  \fi
  \advance\kvvarno by -1
\else
  \let\next=\relax
\fi
\next
}
%%
\def\veitchchart#1#2#3#4#5{%
%%
%% #1 is the number of variables in the Veitch chart
%% #2 is the identifier of the function
%% #3 is the list of identifiers of those variables 
%% #4 is the list of tokens that have to be written into the chart
%% #5 is something that you want to draw inside the Veitch chart
%%
\kvvarno=#1  % \kvvarno is the total number of variables 
\kvyvarno=#1 % \kvyvarno is the number of variable marks at the left 
\divide\kvyvarno by 2
\kvxvarno=#1 % \kvxvarno is the number of variable marks on top 
\advance\kvxvarno by -\kvyvarno
\kvxsize=1
\kvpoweroftwo{\kvxsize}{\kvxvarno}
\kvysize=1
\kvpoweroftwo{\kvysize}{\kvyvarno}
\advance\kvxsize by \kvyvarno
\advance\kvxvarno by \kvysize
\unitlength\kvunitlength
\begin{picture}(\kvxsize,\kvxvarno)(-\kvyvarno,-\kvysize)
\advance\kvxsize by -\kvyvarno
\advance\kvxvarno by -\kvysize
\put(0,-\kvysize){%
\begin{picture}(\kvxsize,\kvysize)
\multiput(0,0)(0,1){\kvysize}{\line(1,0){\kvxsize}}
\multiput(0,0)(1,0){\kvxsize}{\line(0,1){\kvysize}}
\put(0,\kvysize){\line(1,0){\kvxsize}}
\put(\kvxsize,0){\line(0,1){\kvysize}}
#5
\end{picture}}
\put(-\kvyvarno,0){\makebox(\kvyvarno,\kvxvarno){#2}}
\kvindexcounter=0
\kvargumentstring{#4}
\put(0,-\kvysize){\veitchmakechart{\kvysize}}
\ifodd\kvvarno
{\divide\kvxsize by 2
\put(\kvxsize,-\kvysize){\veitchmakechart{\kvysize}}}
\fi
\kvargumentstring{#3}
\veitchmakemarks
%%
\end{picture}
}%
%%

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: