%% 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: