%% This is file `tikzlibrarykarnaugh.code.tex' formerly known as `tikz-karnaugh.tex',
%% Version: 1.3
%% Version date: 2021-10-14
%% 
%% Copyright (C) 2018 by Luis Paulo Laus, laus@utfpr.edu.br
%%
%% This package 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 Package' referring to the software
%% `tikzlibrarykarnaugh.code.tex'
%% and its accompanying documentation and `The Copyright Holder'
%% referring to the person Luis Paulo Laus.
%% 
%% 
%% IMPORTANT NOTICE: 
%% 
%% For error reports, comments or suggestions in case of UNCHANGED 
%% versions send mail to:
%% laus@utfpr.edu.br
%% 
\typeout{}
\typeout{Macros for typesetting Karnaugh maps}
\typeout{Version 1.3 of 14 October 2021}
\typeout{by Luis Paulo Laus, laus@utfpr.edu.br}
\typeout{}
%%
%% Change History:
%% 1.0: 22 December 2017: Original Version ported from kvmacros.tex
%% 1.1: 10 January 2018: new style for the map outer box. Support for
%% options in the identifiers and values lists. New vertical mode.
%% New keys to enable indices and disable bars. Macro file renamed
%% to proper tikz library file name.
%% 1.2: 19 March 2018: stop using \pgftransformshift, new kmindexpos
%% (kmindexposx and kmindexposy) to control index position, cell
%% typesetting order switched (first content then index), parameter
%% names changed to include ``km'' letters, new binary index mode
%% 1.3: 14 October 2021: New American style KM (for maps with ones
%% and zeros labels surrounding the map). In addition, a new macro for
%% decimal to Gray Code conversion (\pgfmathdectoGray) is provided.
%%
%% Setting up some TikZ parameters for Karnaugh Maps
%%
\tikzset{
  karnaugh/.style={
    disable bars/.is if=disablebars,
    kmbar/.style={|-|},
    kmbar label/.style={},
    kmbar sep/.initial=0.2\kmunitlength,
    kmbar top sep/.initial=1\kmunitlength,
    kmbar left sep/.initial=1\kmunitlength,
    enable indices/.is if=enableindices,
    kmindex/.style={red,font=\tiny},
    kmtoplabel/.style={blue,font=\footnotesize},
    kmleftlabel/.style={blue,font=\footnotesize},
    kmindexposx/.initial=0.2\kmunitlength,
    kmindexposy/.initial=0.8\kmunitlength,
    kmindexpos/.style 2 args={kmindexposx={##1\kmunitlength},kmindexposy={##2\kmunitlength}},
    binary index/.is if=indexbin,
    Gray index/.is if=indexGray,
    American style/.is if=Americanstyle,
    kmcell/.style={},
    kmvar/.style={},
    kmbox/.style={},
    kmlines/.style={},
    every karnaugh/.try,
  }
}

%%
%% New ifs for the options above
%%
\newif\ifenableindices
\enableindicesfalse
\newif\ifindexGray
\indexGrayfalse
\newif\ifdisablebars
\disablebarsfalse
\newif\ifindexbin
\indexbinfalse
\newif\ifAmericanstyle
\Americanstylefalse
%%
%% We need a fixed dimension for a single field in a Karnaugh map
%% and also, an auxiliary dimension to place the bars.
%%
\newdimen\kmunitlength
\newdimen\kmtemplength
\kmunitlength=8mm
%%
%% First, we have to introduce some counters:
%%
%% \kmrecursiondepth is used to control the recursion of the
%% \karnaughmakemap macro.
%%
\newcount\kmrecursiondepth
%%
%% The \kmindexcounter is needed for the indices in the fields of the
%% diagrams. 
%%
\newcount\kmindexcounter
%% 
%% \kmxsize and \kmysize store the dimensions of an entire diagram.
%%
\newcount\kmxsize
\newcount\kmysize
%%
%% Some counters are necessary to compute the bars for the variable
%% identifiers:
%%
\newcount\kmvarno
\newcount\kmxvarno
\newcount\kmyvarno
\newcount\kmbarstart
\newcount\kmbarlength
\newcount\kmbarnum
\newcount\kmbarmove
\newcount\kmtemppos
%%
%% Single cells in a diagram should be indexed, which makes the map easier to
%% use (ok, not really, but it might be useful).
%%
\def\kmcurrentindex{\kmcurrentindexdec}
\def\kmcurrentindexdec{%
    \the\kmindexcounter\global\advance\kmindexcounter by 1}%
\def\kmcurrentindexbin{%
    \kmdectobin{\kmindexcounter}\global\advance\kmindexcounter by 1}%
\def\kmcurrentindexGray{%
    \kmdectoKG{\kmindexcounter}\global\advance\kmindexcounter by 1}%
\def\kmcurrentindexGrayvert{%
    \kmdectoKGvert{\kmindexcounter}\global\advance\kmindexcounter by 1}%
%%
%% We need a macro that computes the powers of two:
%%
\def\kmpoweroftwo#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
    \kmpoweroftwo{#1}{#2}
  \fi}}
%%
%% \pgfmathdectoGray
%%
%% Convert a representation of an integer from
%% base 10 to Gray Code.
%%
%% #1 - a macro to store the result.
%% #2 - a number in base 10 (in a macro, not a register)
%%
%% e.g.
%%
%% \pgfmathdectoGray\mynumber{9}
%%
%% \mynumber <- 1101
%%
{\makeatletter
\gdef\pgfmathdectoGray#1#2{%
    \pgfmathdectobase{\pgfresult@}{#2}{2}%
    \c@pgfmath@counta=0\relax%
    \let\pgfresult@@=\pgfmath@empty%
    \let\pgf@lib@sh@next\pgfmathdectoGray@%
    \expandafter\pgfmathdectoGray@\pgfresult@\pgf@stop%
    \let#1=\pgfresult@@%
    \pgfmath@ensurenumberlength{#1}}
\gdef\pgfmathdectoGray@#1{%
    \ifx#1\pgf@stop%
        \let\pgf@lib@sh@next\relax%
    \else%
        \edef\pgfresult@@{\pgfresult@@\ifnum#1=\c@pgfmath@counta\relax0\else1\fi}%
        \c@pgfmath@counta=#1\relax%
    \fi%
    \pgf@lib@sh@next}
%%
%% The macros \kmdectoKG converts the cell index
%% to a binary code that resembles Gray code 
%% deinterleaving the variables 
%%
\gdef\kmdectoKG#1{%
    \kmbarnum=#1\relax% decimal number to be converted
    \kmbarlength=\kmvarno\relax% number of bits
    \let\kmresult@=\empty
    \let\kmresult@@=\empty
    \let\next\kmdectoKG@%
    \next%
    \kmresult@@\kmresult@}
\gdef\kmdectoKGvert#1{%
    \kmbarnum=#1\relax% decimal number to be converted
    \kmbarlength=\kmvarno\relax% number of bits
    \let\kmresult@=\empty
    \let\kmresult@@=\empty
    \let\next\kmdectoKG@%
    \next%
    \kmresult@\kmresult@@}
\gdef\kmdectoKG@{%
    \ifnum\kmbarlength=0%
        \let\next\relax%
    \else%
        \edef\kmresult@{\ifodd\kmbarnum1\else0\fi\kmresult@}%
        \divide \kmbarnum by 2%
        \advance\kmbarlength by -1\relax%
        \let\next\kmdectoKG@@%
    \fi%
    \next}
\gdef\kmdectoKG@@{%
    \ifnum\kmbarlength=0%
        \let\next\relax%
    \else%
        \edef\kmresult@@{\ifodd\kmbarnum1\else0\fi\kmresult@@}%
        \divide \kmbarnum by 2%
        \advance\kmbarlength by -1\relax%
        \let\next\kmdectoKG@%
    \fi%
    \next}
%%
%% The macros \kmdectobin converts a decimal number
%% passed as argument to binary such that the number of
%% digits (length) is equal to \kmvarno 
%%
%% e.g.
%%
%% \kmvarno=6\relax\kmdectobin{9}
%%
%% 001001
%% 
\gdef\kmdectobin#1{%
    \kmbarnum=#1\relax% decimal number to be converted
    \kmbarlength=\kmvarno\relax% number of bits
    \let\kmresult@=\empty
    \let\next\kmdectobin@%
    \next%
    \kmresult@}
\gdef\kmdectobin@{%
    \ifnum\kmbarlength=0%
        \let\next\relax%
    \else%
        \edef\kmresult@{\ifodd\kmbarnum1\else0\fi\kmresult@}%
        \divide \kmbarnum by 2%
        \advance\kmbarlength by -1\relax%
    \fi%
    \next}
}
%%
%% The macros \kmmakeindexGray creates a Gray coded index
%% inside each cell
%% Deprecated!!! Replaced by a new mechanism based on \kmdectoKG
%%
\def\kmmakeindexGray{
    \kmbarlength=\kmxsize\relax
    \advance\kmbarlength by -1\relax
    \kmtemppos=\kmysize\relax
    \advance\kmtemppos by -1\relax
    \foreach \x in {0,...,\kmbarlength}{
        \foreach \y in {0,...,\kmtemppos}{
            \pgfmathsetbasenumberlength{\kmyvarno}
            \pgfmathdectoGray\mynumbery{\y}
            \pgfmathsetbasenumberlength{\kmxvarno}
            \pgfmathdectoGray\mynumberx{\x}
            \node[shift={((\pgfkeysvalueof{/tikz/kmindexposx},(\pgfkeysvalueof{/tikz/kmindexposy}+\kmtemppos\kmunitlength)},kmindex]  at(\x\kmunitlength,-\y\kmunitlength) {\mynumbery\mynumberx};
        }
    }
}
%%
%% The macros \kmargumentstring and \kmsetoptstr are needed to
%% process the variable-length parameters in \karnaughmap:
%%
\def\kmargumentstring#1{\gdef\kmstringbuf{#1{}\noexpand\end}}
%%
%% The macro \kmsetoptstr reads one token from the list of parameters in
%% \karnaughmap in the form <[opt]>srt and sets the optional style kmtempsty 
%% and saves its contents of the string srt in macro \kmstr
%%
\def\kmsetoptstr{\expandafter\kmgetonetok\kmstringbuf}
%%
%% The macros \kmgetonetok, \kmsplittok and \kmoptstrmake are
%% auxiliary macros used to split the token and save to contents
%%
\def\kmgetonetok#1#2\end{\expandafter\kmsplittok#1{}\end \gdef\kmstringbuf{#2\noexpand\end}}
\def\kmsplittok#1#2\end{\ifx#1[ \kmoptstrmake#2\end \else \kmoptstrmake]#1#2\end \fi}
\def\kmoptstrmake#1]#2\end{\tikzset{kmtempsty/.style={#1}} \edef\kmstr{#2}}%\typeout{Teste #1 e #2}}
%%\def\kmoptstrmake#1]#2\end{Test: #1 and #2.\par}
%%
%% The macro \karnaughmakemap calls itself recursively until the parameter #1
%% equals 1, whereupon it draws one cell contents in a node and, if enabled,
%% another node with the index.
%%
\def\karnaughmakemap#1#2#3#4{{%
  \kmrecursiondepth #1\relax
  \ifnum\kmrecursiondepth>1
    \divide\kmrecursiondepth by 2
    \edef\tempx{#3}
    \edef\tempy{#4}
    \kmtemppos=\tempx\relax
    \advance\kmtemppos by \kmrecursiondepth
    \edef\tempxs{\the\kmtemppos}
    \kmtemppos=\tempy\relax
    \advance\kmtemppos by \kmrecursiondepth
    \edef\tempys{\the\kmtemppos}

    \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:
%% +---+---+
%% | 0 | 1 |
%% +---+---+
%% | 2 | 3 |
%% +---+---+
%%
%% Case 0: top-left Karnaugh map
      \karnaughmakemap{\kmrecursiondepth}{0}{\tempx}{\tempys}%
      \karnaughmakemap{\kmrecursiondepth}{1}{\tempxs}{\tempys}%
      \karnaughmakemap{\kmrecursiondepth}{2}{\tempx}{\tempy}%
      \karnaughmakemap{\kmrecursiondepth}{3}{\tempxs}{\tempy}%
    \or
%% Case 1: top-right Karnaugh map
      \karnaughmakemap{\kmrecursiondepth}{1}{\tempxs}{\tempys}%
      \karnaughmakemap{\kmrecursiondepth}{0}{\tempx}{\tempys}%
      \karnaughmakemap{\kmrecursiondepth}{3}{\tempxs}{\tempy}%
      \karnaughmakemap{\kmrecursiondepth}{2}{\tempx}{\tempy}%
    \or
%% Case 2: bottom-left Karnaugh map
      \karnaughmakemap{\kmrecursiondepth}{2}{\tempx}{\tempy}%
      \karnaughmakemap{\kmrecursiondepth}{3}{\tempxs}{\tempy}%
      \karnaughmakemap{\kmrecursiondepth}{0}{\tempx}{\tempys}%
      \karnaughmakemap{\kmrecursiondepth}{1}{\tempxs}{\tempys}%
    \or
%% Case 3: bottom-right Karnaugh map
      \karnaughmakemap{\kmrecursiondepth}{3}{\tempxs}{\tempy}%
      \karnaughmakemap{\kmrecursiondepth}{2}{\tempx}{\tempy}%
      \karnaughmakemap{\kmrecursiondepth}{1}{\tempxs}{\tempys}%
      \karnaughmakemap{\kmrecursiondepth}{0}{\tempx}{\tempys}%
    \fi
  \else
    \kmsetoptstr{} % reads argument as <[opt]>str
    \node[kmcell,kmtempsty,shift={(0.5\kmunitlength,0.5\kmunitlength)}] at (#3\kmunitlength,#4\kmunitlength){\kmstr};%
    \ifenableindices
      \node[kmindex,shift={(\pgfkeysvalueof{/tikz/kmindexposx},\pgfkeysvalueof{/tikz/kmindexposy})}]
        at (#3\kmunitlength,#4\kmunitlength) {\kmcurrentindex};
    \fi
  \fi}}%
%%
%% \karnaughmaketopbar typesets the variable bars of a Karnaugh map that are
%% located on top of the diagram:
%%
\def\karnaughmaketopbar{%
  \kmbarstart=1
  \kmpoweroftwo{\kmbarstart}{\kmxvarno} % \kmybarstart is the start 
% position for the \foreach
  \kmbarlength=\kmbarstart 
  \multiply\kmbarlength by 2 % \kmbarlength is the length of a bar
  \kmbarmove=\kmbarstart 
  \multiply\kmbarmove by 4 % This is the move distance for the \draw.
  \kmbarnum=\kmxsize
  \divide\kmbarnum by \kmbarmove % This is the number of repetitions for
% the \foreach. 
% The highest-order variable bar needs a special treatment:
  \ifnum\kmbarnum=0\kmbarnum=1\divide\kmbarlength by 2\fi 
  \advance\kmbarmove by \kmbarstart
  \kmtemplength=\pgfkeysvalueof{/tikz/kmbar top sep}
  \multiply \kmtemplength by \kmxvarno
  \advance \kmtemplength by \pgfkeysvalueof{/tikz/kmbar sep}
  \advance \kmtemplength by \kmysize\kmunitlength
  \kmsetoptstr % reads argument as <[opt]>str
  \ifnum\kmbarnum=1
    \draw[kmbar,xshift=\kmbarstart\kmunitlength,yshift=\kmtemplength,kmtempsty]
      (0,0) -- node[above, kmbar label,kmtempsty]{\kmstr} (\kmbarlength\kmunitlength,0);
  \else
    \foreach \x in {\kmbarstart,\kmbarmove,...,\kmxsize}
      \draw[kmbar,xshift=\x\kmunitlength,yshift=\kmtemplength,kmtempsty]
        (0,0) -- node[above, kmbar label,kmtempsty]{\kmstr} (\kmbarlength\kmunitlength,0);
  \fi
}
%%
%% \karnaughmakeleftbar typesets the variable bars of a Karnaugh map that are
%% located on the left of the diagram:
%%
\def\karnaughmakeleftbar{%
  \kmbarstart=1
  \kmpoweroftwo{\kmbarstart}{\kmyvarno} % \kmbarstart is the start 
% position for the \foreach
  \kmbarlength=\kmbarstart 
  \multiply\kmbarlength by 2 % \kmbarlength is the length of a bar
  \kmbarmove=\kmbarstart 
  \multiply\kmbarmove by 4 % This now is the move distance for the
% \foreach. 
  \kmbarnum=\kmysize
  \divide\kmbarnum by \kmbarmove % This now is the number of 
% repetitions for the \draw. 
%The highest-order variable bar needs a special treatment:
  \ifnum\kmbarnum=0\kmbarstart=0\kmbarnum=1\divide\kmbarlength by 2\fi 
  \advance\kmbarmove by \kmbarstart
  \kmtemplength=-\pgfkeysvalueof{/tikz/kmbar left sep}
  \multiply \kmtemplength by \kmyvarno
  \advance \kmtemplength by -\pgfkeysvalueof{/tikz/kmbar sep}
  \kmsetoptstr % reads argument as <[opt]>str
  \ifnum\kmbarnum=1
    \draw[kmbar,yshift=\kmbarstart\kmunitlength,xshift=\kmtemplength,kmtempsty]
      (0,0) -- node[left,kmbar label,kmtempsty]{\kmstr} (0,\kmbarlength\kmunitlength);
  \else
    \foreach \y in {\kmbarstart,\kmbarmove,...,\kmysize}
      \draw[kmbar,yshift=\y\kmunitlength,xshift=\kmtemplength,kmtempsty]
        (0,0) -- node[left,kmbar label,kmtempsty]{\kmstr} (0,\kmbarlength\kmunitlength);
  \fi
}
%% \karnaughmakebars calls \karnaughmaketopbar or \karnaughmakeleftbar
%% depending on whether \kmvarno is odd or even.
%%
\def\karnaughmakebars{%
  \ifnum\kmvarno>0
    \let\next=\karnaughmakebars
    \ifodd\kmvarno % We have to make a bar at the top
      \advance\kmxvarno by -1
      \karnaughmaketopbar
    \else % We have to make a bar at the left
      \advance\kmyvarno by -1
      \karnaughmakeleftbar
    \fi
    \advance\kmvarno by -1
  \else
    \let\next=\relax
  \fi
  \next
}

%% \karnaughmakelabels is a modification of \karnaughmakebars.
%% Instead of making the bars it sets two macros, \kmtoplabels
%% and \kmleftlabels, with the labels for American style maps
%%
\def\karnaughmakelabels{%
  \ifnum\kmvarno>0
    \let\next=\karnaughmakelabels
    \ifodd\kmvarno % We have to make the label for top
      \advance\kmxvarno by -1
      \kmsetoptstr % reads argument as <[opt]>str
      \ifx\kmtoplabels\empty
        \xdef\kmtoplabels{\kmstr}
      \else
        \xdef\kmtoplabels{\kmtoplabels, \kmstr}
      \fi
    \else          % We have to make the label for left
      \advance\kmyvarno by -1
      \kmsetoptstr % reads argument as <[opt]>str
      \ifx\kmleftlabels\empty
        \xdef\kmleftlabels{\kmstr}
      \else
        \xdef\kmleftlabels{\kmleftlabels, \kmstr}
      \fi
    \fi
    \advance\kmvarno 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 a possibly empty set of TikZ commands that will be drown before
%% the function values so the values will appear on top of them
%%
  \kmvarno=#1 % \kmvarno is the total number of variables 
  \kmyvarno=#1 % \kmyvarno is the number of variable bars at the left 
  \divide\kmyvarno by 2
  \kmxvarno=#1 % \kmxvarno is the number of variable bars on top 
  \advance\kmxvarno by -\kmyvarno
  \kmxsize=1
  \kmpoweroftwo{\kmxsize}{\kmxvarno}
  \kmysize=1
  \kmpoweroftwo{\kmysize}{\kmyvarno}
  \kmtemppos=\kmxsize
  \advance\kmtemppos by -1
  \kmtemplength=\pgfkeysvalueof{/tikz/kmbar top sep}
  \foreach \x in {1,...,\kmtemppos}
    \draw[kmlines] (\x\kmunitlength,0) -- (\x\kmunitlength,\kmysize\kmunitlength);
  \kmtemppos=\kmysize
  \advance\kmtemppos by -1
  \ifnum\kmtemppos>0
    \foreach \y in {1,...,\kmtemppos}
      \draw[kmlines] (0,\y\kmunitlength) -- (\kmxsize\kmunitlength,\y\kmunitlength);
  \fi
  \draw[kmbox] (0,0) rectangle (\kmxsize\kmunitlength,\kmysize\kmunitlength);
  #5
  \ifAmericanstyle
    \pgfmathsetbasenumberlength{\kmxvarno}
    \kmtemppos=\kmxsize
    \advance\kmtemppos by -1
    \kmtemplength=\pgfkeysvalueof{/tikz/kmbar top sep}
    \pgfmathsetbasenumberlength{\kmxvarno}
    \foreach \x in {0,...,\kmtemppos}
       \node[xshift=0.5\kmunitlength, yshift=\kmtemplength,kmtoplabel] at (\x\kmunitlength,\kmysize\kmunitlength)  {\pgfmathdectoGray\mynumber{\x}\mynumber};
    \kmtemppos=\kmysize
    \advance\kmtemppos by -1
    \ifnum\kmtemppos>0
      \kmtemplength=\pgfkeysvalueof{/tikz/kmbar left sep}
      \pgfmathsetbasenumberlength{\kmyvarno}
      \foreach \y in {0,...,\kmtemppos}
        \node[xshift=-\kmtemplength, yshift=\kmysize\kmunitlength-0.5\kmunitlength,left,kmleftlabel] at (0,-\y\kmunitlength)  {\pgfmathdectoGray\mynumber{\y}\mynumber};
    \fi
    \kmargumentstring{#3}
    \gdef\kmtoplabels{}
    \gdef\kmleftlabels{}
    \karnaughmakelabels 
    \draw[kmbox] (0,\kmysize\kmunitlength) -- ++(135:1\kmunitlength) node[kmbar label,below left,pos=0.5]{\kmleftlabels} node[kmbar label,above right,pos=0.5]{\kmtoplabels} node[kmvar,above left]{#2};
  \else
    \ifdisablebars\relax\else
      \node[kmvar,above left] at (0,\kmysize\kmunitlength){#2};
      \kmargumentstring{#3}
      \karnaughmakebars
    \fi
  \fi
  \ifenableindices
     \ifindexbin
        \gdef\kmcurrentindex{\kmcurrentindexbin}
        \pgfmathsetbasenumberlength{#1}
     \else
        \ifindexGray
           \gdef\kmcurrentindex{\kmcurrentindexGray}
        \else
           \gdef\kmcurrentindex{\kmcurrentindexdec}
        \fi
     \fi
  \fi
  \kmvarno=#1 % \kmvarno is the total number of variables 
  \kmindexcounter=0
  \kmargumentstring{#4}
  \karnaughmakemap{\the\kmysize}{0}{0}{0}
  \ifodd\kmvarno
    \divide\kmxsize by 2
    \karnaughmakemap{\the\kmysize}{1}{\the\kmxsize}{0}
  \fi
}%
%% Vertical Mode
%% The next three macros are similar to the ones for normal mode.
%% The macro \karnaughmakemapvert calls itself recursively until the parameter #1
%% equals 1, whereupon it draws one cell contents in a node and, if enabled,
%% another node with the index.
%%
\def\karnaughmakemapvert#1#2#3#4{{%
  \kmrecursiondepth #1\relax
  \ifnum\kmrecursiondepth>1
    \divide\kmrecursiondepth by 2
    \edef\tempx{#3}
    \edef\tempy{#4}
    \kmtemppos=\tempx\relax
    \advance\kmtemppos by \kmrecursiondepth
    \edef\tempxs{\the\kmtemppos}
    \kmtemppos=\tempy\relax
    \advance\kmtemppos by \kmrecursiondepth
    \edef\tempys{\the\kmtemppos}

    \ifcase#2
%%
%% The parameter #2 of \karnaughmakemapvert 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:
%% +---+---+
%% | 0 | 2 |
%% +---+---+
%% | 1 | 3 |
%% +---+---+
%%
%% Case 0: top-left Karnaugh map
      \karnaughmakemapvert{\kmrecursiondepth}{0}{\tempx}{\tempys}%
      \karnaughmakemapvert{\kmrecursiondepth}{1}{\tempx}{\tempy}%
      \karnaughmakemapvert{\kmrecursiondepth}{2}{\tempxs}{\tempys}%
      \karnaughmakemapvert{\kmrecursiondepth}{3}{\tempxs}{\tempy}%
    \or
%% Case 1: bottom-left Karnaugh map
      \karnaughmakemapvert{\kmrecursiondepth}{1}{\tempx}{\tempy}%
      \karnaughmakemapvert{\kmrecursiondepth}{0}{\tempx}{\tempys}%
      \karnaughmakemapvert{\kmrecursiondepth}{3}{\tempxs}{\tempy}%
      \karnaughmakemapvert{\kmrecursiondepth}{2}{\tempxs}{\tempys}%
    \or
%% Case 2: top-right Karnaugh map
      \karnaughmakemapvert{\kmrecursiondepth}{2}{\tempxs}{\tempys}%
      \karnaughmakemapvert{\kmrecursiondepth}{3}{\tempxs}{\tempy}%
      \karnaughmakemapvert{\kmrecursiondepth}{0}{\tempx}{\tempys}%
      \karnaughmakemapvert{\kmrecursiondepth}{1}{\tempx}{\tempy}%
    \or
%% Case 3: bottom-right Karnaugh map
      \karnaughmakemapvert{\kmrecursiondepth}{3}{\tempxs}{\tempy}%
      \karnaughmakemapvert{\kmrecursiondepth}{2}{\tempxs}{\tempys}%
      \karnaughmakemapvert{\kmrecursiondepth}{1}{\tempx}{\tempy}%
      \karnaughmakemapvert{\kmrecursiondepth}{0}{\tempx}{\tempys}%
    \fi
  \else
    \kmsetoptstr{} % reads argument as <[opt]>str
    \node[kmcell,kmtempsty,shift={(0.5\kmunitlength,0.5\kmunitlength)}] at (#3\kmunitlength,#4\kmunitlength){\kmstr};
    \ifenableindices
      \node[kmindex,shift={(\pgfkeysvalueof{/tikz/kmindexposx},\pgfkeysvalueof{/tikz/kmindexposy})}]
        at (#3\kmunitlength,#4\kmunitlength) {\kmcurrentindex};
    \fi
  \fi}}%
%%
%% \karnaughmakebarsvert calls \karnaughmaketopbar or \karnaughmakeleftbar
%% depending on whether \kmvarno is odd or even.
%%
\def\karnaughmakebarsvert{%
  \ifnum\kmvarno>0
    \let\next=\karnaughmakebarsvert
    \ifodd\kmvarno % We have to make a bar at the left
      \advance\kmyvarno by -1
      \karnaughmakeleftbar 
    \else          % We have to make a bar at the top
      \advance\kmxvarno by -1
      \karnaughmaketopbar
    \fi
    \advance\kmvarno by -1
  \else
    \let\next=\relax
  \fi
  \next
}

%% \karnaughmakelabelsvert is a modification of \karnaughmakebars.
%% Instead of making the bars it sets two macros, \kmtoplabels
%% and \kmleftlabels, with the labels for americal style maps
%%
\def\karnaughmakelabelsvert{%
  \ifnum\kmvarno>0
    \let\next=\karnaughmakelabelsvert
    \ifodd\kmvarno % We have to make the label for left
      \advance\kmyvarno by -1
      \kmsetoptstr % reads argument as <[opt]>str
      \ifx\kmleftlabels\empty
        \xdef\kmleftlabels{\kmstr}
      \else
        \xdef\kmleftlabels{\kmleftlabels, \kmstr}
      \fi
    \else          % We have to make the label for top
      \advance\kmxvarno by -1
      \kmsetoptstr % reads argument as <[opt]>str
      \ifx\kmtoplabels\empty
        \xdef\kmtoplabels{\kmstr}
      \else
        \xdef\kmtoplabels{\kmtoplabels, \kmstr}
      \fi
    \fi
    \advance\kmvarno by -1
  \else
    \let\next=\relax
  \fi
  \next
}
%%
%% \karnaughmapvert is the macro that a user calls if he wants to draw a
%% Karnaugh map in vertical mode (not be confused with TeX vertical mode): 
%%
\def\karnaughmapvert#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 a possibly empty set of TikZ commands that will be drown before
%% the function values so the values will appear on top of them
%%
  \kmvarno=#1 % \kmvarno is the total number of variables 
  \kmxvarno=#1 % \kmxvarno is the number of variable bars on top
  \divide\kmxvarno by 2
  \kmyvarno=#1 % \kmyvarno is the number of variable bars at the left
  \advance\kmyvarno by -\kmxvarno
  \kmxsize=1
  \kmpoweroftwo{\kmxsize}{\kmxvarno}
  \kmysize=1
  \kmpoweroftwo{\kmysize}{\kmyvarno}
  \kmtemppos=\kmxsize
  \advance\kmtemppos by -1
  \ifnum\kmtemppos>0
    \foreach \x in {1,...,\kmtemppos}
      \draw[kmlines] (\x\kmunitlength,0) -- (\x\kmunitlength,\kmysize\kmunitlength);
  \fi
  \kmtemppos=\kmysize
  \advance\kmtemppos by -1
  \foreach \y in {1,...,\kmtemppos}
    \draw[kmlines] (0,\y\kmunitlength) -- (\kmxsize\kmunitlength,\y\kmunitlength);
  \draw[kmbox] (0,0) rectangle (\kmxsize\kmunitlength,\kmysize\kmunitlength);
  #5
  \ifAmericanstyle
    \pgfmathsetbasenumberlength{\kmxvarno}
    \kmtemppos=\kmxsize
    \advance\kmtemppos by -1
    \kmtemplength=\pgfkeysvalueof{/tikz/kmbar top sep}
    \pgfmathsetbasenumberlength{\kmxvarno}
    \foreach \x in {0,...,\kmtemppos}
       \node[xshift=0.5\kmunitlength, yshift=\kmtemplength,kmtoplabel] at (\x\kmunitlength,\kmysize\kmunitlength)  {\pgfmathdectoGray\mynumber{\x}\mynumber};
    \kmtemppos=\kmysize
    \advance\kmtemppos by -1
    \ifnum\kmtemppos>0
      \kmtemplength=\pgfkeysvalueof{/tikz/kmbar left sep}
      \pgfmathsetbasenumberlength{\kmyvarno}
      \foreach \y in {0,...,\kmtemppos}
        \node[xshift=-\kmtemplength, yshift=\kmysize\kmunitlength-0.5\kmunitlength,left,kmleftlabel] at (0,-\y\kmunitlength)  {\pgfmathdectoGray\mynumber{\y}\mynumber};
    \fi
    \kmargumentstring{#3}
    \gdef\kmtoplabels{}
    \gdef\kmleftlabels{}
    \karnaughmakelabelsvert
    \draw[kmbox] (0,\kmysize\kmunitlength) -- ++(135:1\kmunitlength) node[kmbar label,below left,pos=0.5]{\kmleftlabels} node[kmbar label,above right,pos=0.5]{\kmtoplabels} node[kmvar,above left]{#2};
  \else
    \ifdisablebars\relax\else
      \node[kmvar,above left] at (0,\kmysize\kmunitlength){#2};
      \kmargumentstring{#3}
      \karnaughmakebarsvert
    \fi
  \fi
  \ifenableindices
     \ifindexbin
        \gdef\kmcurrentindex{\kmcurrentindexbin}
        \pgfmathsetbasenumberlength{#1}
     \else
        \ifindexGray
           \gdef\kmcurrentindex{\kmcurrentindexGrayvert}
        \else
           \gdef\kmcurrentindex{\kmcurrentindexdec}
        \fi
     \fi
  \fi
  \kmvarno=#1 % \kmvarno is the total number of variables 
  \kmindexcounter=0
  \kmargumentstring{#4}
  \ifodd\kmvarno
    \divide\kmysize by 2
    \karnaughmakemapvert{\the\kmxsize}{0}{0}{\the\kmysize}
    \karnaughmakemapvert{\the\kmxsize}{1}{0}{0}
  \else
    \karnaughmakemapvert{\the\kmxsize}{0}{0}{0}
  \fi
}%

\endinput