\def\yquant@register@types@nobit{0} \def\yquant@register@types@qubit{1} \def\yquant@register@types@cbit{2} \def\yquant@register@types@qubits{3} \csdef{yquant@register@type@tostring@0}{nobit} \csdef{yquant@register@type@tostring@1}{qubit} \csdef{yquant@register@type@tostring@2}{cbit} \csdef{yquant@register@type@tostring@3}{qubits} \def\yquant@register@type@tostring#1{% \ifcsname yquant@register@type@tostring@#1\endcsname% \csname yquant@register@type@tostring@#1\endcsname% \else% \PackageError{yquant.sty}{Internal inconsistency detected}% {Unknown wire type: `#1'.}% \fi% } \protected\def\yquant@register@type@fromstring#1#2{% \ifyquant@AND% \ifcsname yquant@register@types@#1\endcsname\fi% \ifnum\csname yquant@register@types@#1\endcsname>0 \fi{% \letcs#2{yquant@register@types@#1}% }{% \PackageError{yquant.sty}{Invalid bit type: `#1'}% {Use one of `qubit', `cbit', or `qubits'.}% }% } % Internally, we store the register information in a single macro. Indeed, this is almost always faster than using multiple macros (at least in the way implemented here), apart from changing a single type of information, which is almost as fast. % BEGIN_FOLD Constructor: create single register and cleanup environment % #1: type % #2: name % #3: index \protected\def\yquant@register@define#1#2#3{% \csnumgdef{\yquant@prefix registers}% {\csname\yquant@prefix registers\endcsname+1}% % sync with yquantlanguage-groups/\yquantgroup@startenvironment \csxdef{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}{% {#1}% type {0pt}% x pos {{\yquant@config@register@minimum@height}% {\yquant@config@register@minimum@depth}% {}}% height, depth, and multi-space parts; at the end, the y position {{0pt}{0pt}{}{}}% wire start positions and clipping {}% wire style {\yquant@register@flag@clean}% information about the last gate }% \global\csletcs{\yquant@prefix registername@#2[#3]}{\yquant@prefix registers}% \csxdef{\yquant@prefix registerhigh@#2}{#3}% \expandafter\expandafter\expandafter\yquant@circuit@enclose@update@extentTB% \expandafter\expandafter\expandafter T% \expandafter\expandafter\expandafter{\csname\yquant@prefix registers\endcsname}% {0pt}% just to make it known \yquant@cleanup@csadd{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}% \yquant@cleanup@csadd{\yquant@prefix registername@#2[#3]}% \ifnum0=#3\relax% \yquant@cleanup@csadd{\yquant@prefix registerhigh@#2}% \fi% } % in a subcircuit, create a new register that is only an alias for an existing register in the outer circuit. % #4: id in the outer circuit \protected\def\yquant@register@alias#1#2#3#4{% \csnumgdef{\yquant@prefix registers}% {\csname\yquant@prefix registers\endcsname+1}% \ifcsname\yquant@parent registermap@#4\endcsname% % the parent is already an alias itself, pass this on transparently \global\csletcs% {\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname}% {\yquant@parent registermap@#4}% \else% \csxdef{\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname}% {\yquant@parent register@#4}% \fi% % we still store height, depth, and multi-space parts. To keep the same macros, we create a full register structure, but "abuse" the type component to contain the direct parent \csxdef{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}{% {{\yquant@env@prefix@id\yquant@parent}{#4}}% direct parent {circuit id}{register id} {}% unused {{\yquant@config@register@minimum@height}% {\yquant@config@register@minimum@depth}% {}}% height, depth, and multi-space parts {}% unused {}% unused {}% unused }% \global\csletcs{\yquant@prefix registername@#2[#3]}{\yquant@prefix registers}% \csxdef{\yquant@prefix registerhigh@#2}{#3}% \expandafter\expandafter\expandafter\yquant@circuit@enclose@update@extentTB% \expandafter\expandafter\expandafter T% \expandafter\expandafter\expandafter{\csname\yquant@prefix registers\endcsname}% {0pt}% just to make it known \yquant@cleanup@csadd{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}% \yquant@cleanup@csadd{\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname}% \yquant@cleanup@csadd{\yquant@prefix registername@#2[#3]}% \ifnum0=#3\relax% \yquant@cleanup@csadd{\yquant@prefix registerhigh@#2}% \fi% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname\endcsname\endcsname% \yquant@register@set@typelastgate@aux% {{#1}{\yquant@register@flag@clean}}% } % END_FOLD % expand to #2 if #1 has an alias and to #3 else \def\ifyquant@register@isaliased#1{% \ifyquant\ifcsname\yquant@prefix registermap@#1\endcsname\fi% } % BEGIN_FOLD Handling fully-qualified register names % we sometimes have to store etoolbox lists that contain both circuit ids as well as registers; we do this in the form :, as the more convenient grouping is not possible. However, during iteration we then need to have them split again; so we can then simply do a \forlistloop{\yquant@register@colonsplit{}}\list. \long\def\yquant@register@colonsplit#1#2{% \yquant@register@colonsplit@#2\yquant@sep{#1}% } \long\def\yquant@register@colonsplitcs#1#2{% \expandafter\expandafter\expandafter\yquant@register@colonsplit@\csname#2\endcsname\yquant@sep{#1}% } \long\def\yquant@register@colonsplit@#1:#2\yquant@sep#3{% #3{#1}{#2}% } \def\yquant@register@colonprefix#1{\yquant@register@colonprefix@#1\yquant@sep} \def\yquant@register@colonprefix@#1:#2\yquant@sep{#1} \def\yquant@register@colonsuffix#1{\yquant@register@colonsuffix@#1\yquant@sep} \def\yquant@register@colonsuffix@#1:#2\yquant@sep{#2} \def\yquant@register@resolvetocolon#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter\yquant@register@resolve@alias% \csname\yquant@prefix registermap@#1\endcsname% \yquant@sep% \else% \yquant@env@prefix@id\yquant@prefix:#1% \fi% } \def\yquant@register@fullresolvetocolon#1#2{% \ifcsname yquant@env#1@registermap@#2\endcsname% \expandafter\expandafter\expandafter\yquant@register@resolve@alias% \csname yquant@env#1@registermap@#2\endcsname% \yquant@sep% \else% #1:#2% \fi% } \def\yquant@register@resolve@alias yquant@env#1@register@#2\yquant@sep{#1:#2}% % END_FOLD % BEGIN_FOLD Ordering registers % expand to #6 if register with circuit #1 and id #2 is numerically ordered according to operator #3 with respect to register with circuit #4 and id #5; and to #7 else. % This respects subcircuit ordering. Note that some registers might not have any defined ordering, in which case #8 is expanded. \protected\def\ifnumyquant@registers#1#2#3#4#5{% % There are various situations: \ifyquant\ifnum#1=#4 \fi{% % 1. #1 = #4, i.e., they are both within the same circuit. Just compare the numbers. \ifnumyquant@registers@ifnum{#2}#3{#5} }{% \begingroup% % resolve all aliases \ifcsname yquant@env#1@registermap@#2\endcsname% \ifnumyquant@registers@extractcs\circuitA\idA{yquant@env#1@registermap@#2}% \else% \edef\circuitA{#1}% \edef\idA{#2}% \fi% \ifcsname yquant@env#4@registermap@#5\endcsname% \ifnumyquant@registers@extractcs\circuitB\idB{yquant@env#4@registermap@#5}% \else% \edef\circuitB{#4}% \edef\idB{#5}% \fi% \ifyquant\ifx\circuitA\circuitB\fi{% % 2. both wires alias into the same circuit; just compare the original numbers. \ifnum\idA#3\idB\space% \endgroup% \expandafter\@firstoftwo% \else% \endgroup% \expandafter\@secondoftwo% \fi% }{% % 3. both wires don't alias or not in the same circuit % check which circuit has fewer wires and call it A, the other B \ifnum\csname yquant@env\circuitA @registers\endcsname>\csname yquant@env\circuitB @registers\endcsname\space% % reverse \let\theifnum=\ifnumyquant@registers@ifnum@reverse% \let\iterCircuitA=\circuitB% \let\iterIdA=\idB% \let\iterCircuitB=\circuitA% \let\iterIdB=\idA% \else% \let\theifnum=\ifnumyquant@registers@ifnum% \let\iterCircuitA=\circuitA% \let\iterIdA=\idA% \let\iterCircuitB=\circuitB% \let\iterIdB=\idB% \fi% % iterate through all wires in circuit A apart from the already useless-proven wire A, building up a dictionary of all wires, noting in which circuit they point and if above or below. \undef\idA% \undef\idB% \let\next=\@firstofone% \ifyquant@registers@buildAllBefore\iterCircuitA\iterIdA% \next{% \ifyquant@registers@checkAllAfter\iterCircuitB\iterIdB% }% \next{% \ifyquant@registers@buildAllAfter\iterCircuitA\iterIdA% }% \next{% \ifyquant@registers@checkAllBefore\iterCircuitB\iterIdB% }% \ifyquant\ifx\next\@firstofone\fi{% \endgroup% \@thirdofthree% }{% \expandafter\expandafter\expandafter\endgroup% \theifnum\idA#3\idB% }% }% }% } \protected\def\ifyquant@registers@buildAllBefore#1#2{% % create macros for each and every wire that can rightfully be said to be above or equal to circuit #1, id #2 \ifyquant\ifcsname ifnumyquant@register@circuitA@before@#1@#2\endcsname\fi\relax{% \let\collection=\empty% \yquant@fordown \i := #2 downto 1 {% \ifyquant@AND\ifnum#1=\iterCircuitB\space\fi% \unless\ifnum\i<\iterIdB\space\fi{% % we explicitly found the required wire B before A, so A > B \def\idA{2}\def\idB{1}\let\next=\@gobble% \yquant@for@break% }{% \ifcsname yquant@env#1@registermap@\i\endcsname% \ifnumyquant@registers@extractcs\circuit\id{yquant@env#1@registermap@\i}% \eappto\collection{% \ifyquant@registers@buildAllBefore{\circuit}{\id}% }% \else% % this is not an alias - which means it might be an ancilla. So now we have to check all the registers _after_ \i until we find the first one that is an alias. Then, we have to resolve this alias and add everything that is strictly above it. \yquant@for \j := \numexpr\i+1\relax to \csname yquant@env#1@registers\endcsname {% \ifyquant\ifcsname yquant@env#1@registermap@\j\endcsname\fi{% \ifnumyquant@registers@extractcs\circuit\id{yquant@env#1@registermap@\j}% \ifnum\id>1 % \eappto\collection{% \ifyquant@registers@buildAllBefore{\circuit}{\the\numexpr\id-1\relax}% }% \fi% \yquant@for@break% }\relax% }% \cslet{ifnumyquant@register@circuitA@before@#1@\i}\relax% \fi% }% }% \next\collection% }% } \protected\def\ifyquant@registers@buildAllAfter#1#2{% % create macros for each and every wire that can rightfully be said to be below circuit #1, id #2 \ifyquant\ifcsname ifnumyquant@register@circuitA@after@#1@#2\endcsname\fi\relax{% \let\collection=\empty% \yquant@for \i := #2 to \csname yquant@env#1@registers\endcsname {% \ifyquant@AND\ifnum#1=\iterCircuitB\space\fi% \unless\ifnum\i>\iterIdB\space\fi{% % we explicitly found the required wire B after A, so A < B \def\idA{1}\def\idB{2}\let\next=\@gobble% \yquant@for@break% }{% \ifcsname yquant@env#1@registermap@\i\endcsname% \ifnumyquant@registers@extractcs\circuit\id{yquant@env#1@registermap@\i}% \eappto\collection{% \ifyquant@registers@buildAllAfter{\circuit}{\id}% }% \else% % this is not an alias - which means it might be an ancilla. So now we have to check all the registers _before_ \i until we find the first one that is an alias. Then, we have to resolve this alias and add everything that is strictly below it. \yquant@fordown \j := \numexpr\i-1\relax downto 1 {% \ifyquant\ifcsname yquant@env#1@registermap@\j\endcsname\fi{% \ifnumyquant@registers@extractcs\circuit\id{yquant@env#1@registermap@\j}% \ifnum\id<\csname yquant@env#1@registers\endcsname\space% \eappto\collection{% \ifyquant@registers@buildAllBefore{\circuit}{\the\numexpr\id+1\relax}% }% \fi% \yquant@for@break% }\relax% }% \cslet{ifnumyquant@register@circuitA@after@#1@\i}\relax% \fi% }% }% \next\collection% }% } \protected\def\ifyquant@registers@checkAllBefore#1#2{% % check that we cannot find any after macro for any wire that can rightfully be said to be above circuit #1, id #2 \let\collection=\empty% \yquant@fordown \i := \numexpr#2-1\relax downto 1 {% \ifyquant\ifcsname yquant@env#1@registermap@\i\endcsname\fi{% \ifnumyquant@registers@extractcs\circuit\id{yquant@env#1@registermap@\i}% \ifyquant\ifcsname ifnumyquant@registers@circuitA@after@\circuit @\id\endcsname\fi{% % we found something that is after A but before B, hence A < B \def\idA{1}\def\idB{2}\let\next=\@gobble% \yquant@for@break% }{% \eappto\collection{% \noexpand\next{\ifyquant@registers@checkAllBefore{\circuit}{\id}}% } }% }{% \ifyquant\ifcsname ifnumyquant@registers@circuitA@after@#1@\i\endcsname\fi{% \def\idA{1}\def\idB{2}\let\next=\@gobble% \yquant@for@break% }\relax% }% }% \next\collection% } \protected\def\ifyquant@registers@checkAllAfter#1#2{% % check that we cannot find any before macro for any wire that can rightfully be said to be below circuit #1, id #2 \let\collection=\empty% \yquant@for \i := \numexpr#2+1\relax to \csname yquant@env#1@registers\endcsname {% \ifyquant\ifcsname yquant@env#1@registermap@\i\endcsname\fi{% \ifnumyquant@registers@extractcs\circuit\id{yquant@env#1@registermap@\i}% \ifyquant\ifcsname ifnumyquant@registers@circuitA@before@\circuit @\id\endcsname\fi{% % we found something that is before A but after B, hence B < A \def\idA{2}\def\idB{1}\let\next=\@gobble% \yquant@for@break% }{% \eappto\collection{% \noexpand\next{\ifyquant@registers@checkAllAfter{\circuit}{\id}}% } }% }{% \ifyquant\ifcsname ifnumyquant@registers@circuitA@before@#1@\i\endcsname\fi{% \def\idA{2}\def\idB{1}\let\next=\@gobble% \yquant@for@break% }\relax% }% }% \next\collection% } \def\ifnumyquant@registers@extractcs#1#2#3{% \expandafter\expandafter\expandafter\ifnumyquant@registers@extract@\csname#3\endcsname\yquant@sep#1#2% } \protected\def\ifnumyquant@registers@extract@ yquant@env#1@register@#2\yquant@sep#3#4{% \def#3{#1}% \def#4{#2}% } \def\ifnumyquant@registers@ifnum#1#2#3{\ifnum#1#2#3 \expandafter\@firstofthree\else\expandafter\@secondofthree\fi} \def\ifnumyquant@registers@ifnum@reverse#1#2#3{\ifnum#3#2#1 \expandafter\@firstofthree\else\expandafter\@secondofthree\fi} % END_FOLD % BEGIN_FOLD Converter: convert a register name to its id % store the number corresponding to register #2 into #1 \protected\def\yquant@register@get@id#1#2{% \ifcsname\yquant@prefix registername@#2\endcsname% \letcs#1{\yquant@prefix registername@#2}% \else% \yquant@register@get@id@lazycreate{#2}% \letcs#1{\yquant@prefix registers}% \fi% } % same as before, but resolves to the _index_ of the last register \protected\def\yquant@register@get@id@high#1#2{% \unless\ifcsname\yquant@prefix registerhigh@#2\endcsname% \yquant@register@get@id@lazycreate{#2}% \fi% \letcs#1{\yquant@prefix registerhigh@#2}% } % In the lazy mode, we create all unknown registers on-the-fly. \def\yquant@register@get@id@lazycreate#1{% \ifyquant@env@lazy% % In principle, we could just call \yquant@lang@@qubit. However, if access to a vector register is desired and a _part_ of this does already exist (though not the requested index), we only create the missing registers. \yquant@register@get@id@lazycreate@parse#1[;% \else% \PackageError{yquant.sty}{Register `#1' unknown}% {You referred to an unknown register. Declare registers first using `qubit' and friends.}% \fi% } \def\yquant@register@get@id@lazycreate@parse#1[#2;{% \ifstrempty{#2}{% \yquant@register@get@id@lazycreate@do#1[0][;% }{% \yquant@register@get@id@lazycreate@do#1[#2;% }% } % sync with \yquant@lang@create@do \protected\def\yquant@register@get@id@lazycreate@do#1[#2]#3[;{% \begingroup% % parse length \ifstrempty{#3}{% \yquant@langhelper@validate\len\count{#2}% \numdef\len{\len+1}% }{% \PackageError{yquant.sty}{Invalid register name}% {Register names must not contain `[' apart from register length indication.}% }% \edef\reg{\trim@spaces{#1}}% % Was this register already defined? \ifcsname\yquant@prefix registerhigh@\reg\endcsname% \numdef\idx{\csname\yquant@prefix registerhigh@\reg\endcsname+1}% \unless\ifnum\idx<\len\relax% \PackageError{yquant.sty}{Internal inconsistency detected}% {Tried to create a register on-the-fly that already existed.}% \fi% \else% \def\idx{0}% \fi% % define text macros \ifnum\len>1 % \def\regidx{\reg[\idx]}% \else% \ifnum\yquant@compat<4 % \let\regidx=\reg% \else% \def\regidx{\reg\vphantom[\yquant@lang@maybe@idx}% \fi% % see comment in \yquant@lang@create@do for the vphantom \fi% \numdef\yquant@circuit@operator@mintarget{\csname\yquant@prefix registers\endcsname+1}% \let\yquant@circuit@enclose@allowmovelabel=\@gobble% \begingroup% \yquant@for \idx := \idx to \numexpr \len -1\relax {% \yquant@prepare@create\reg\idx\yquant@register@types@qubit% }% \endgroup% \ifx\yquant@config@register@default@lazyname\empty% \expandafter\@gobble% \else% \expandafter\@firstofone% \fi% {% \let\yquant@lang@attr@value=\yquant@config@register@default@lazyname% % gather details about the created registers \letcs\yquant@circuit@operator@maxtarget{\yquant@prefix registers}% \numdef\yquant@circuit@operator@numtarget{\yquant@circuit@operator@maxtarget-\yquant@circuit@operator@mintarget+1}% \edef\yquant@circuit@operator@targets{% \yquant@list@range% \yquant@circuit@operator@mintarget% \yquant@circuit@operator@maxtarget% }% \yquant@circuit@operator@hasControlsfalse% \let\yquant@circuit@operator@pctrls=\empty% \def\yquant@circuit@operator@minpctrl{2147483647}% \def\yquant@circuit@operator@maxpctrl{0}% \let\yquant@circuit@operator@numpctrl=\yquant@circuit@operator@maxpctrl% \let\yquant@circuit@operator@nctrls=\empty% \let\yquant@circuit@operator@minnctrl=\yquant@circuit@operator@minpctrl% \let\yquant@circuit@operator@maxnctrl=\yquant@circuit@operator@maxpctrl% \let\yquant@circuit@operator@numnctrl=\yquant@circuit@operator@numpctrl% \let\yquant@circuit@operator@minctrl=\yquant@circuit@operator@mintarget% \let\yquant@circuit@operator@maxctrl=\yquant@circuit@operator@maxtarget% % there are no multi inits in this context \let\yquant@lang@@init@encloserelevant=\empty% \forlistloop\yquant@lang@@init@checkenclose\yquant@circuit@enclose@active% \ifx\yquant@lang@@init@encloserelevant\empty% \preto\yquant@attrs@remaining{internal/move label,}% \else % see comment in \yquant@lang@create@do for the dilemma \epreto\yquant@attrs@remaining{internal/maybe move label={\yquant@config@operator@minimum@width}{\yquant@lang@@init@encloserelevant}}% \fi% \def\yquant@config@operator@minimum@width{0pt}% \epreto\yquant@attrs@remaining{internal/setregidx={\idx}{\reg},}% \unless\ifx\yquant@lang@attr@value\empty% % make sure to immediately remove the "clear" marker again if we have a text \yquant@for \i := \yquant@circuit@operator@mintarget to \yquant@circuit@operator@maxtarget {% \yquant@register@execclear@lastgate{\i}{init}% }% \fi% \let\yquant@circuit@enclose@allowmovelabel=\@gobble% \expandafter\yquant@prepare% \expandafter{\yquant@lang@attr@value}% {/yquant/every label, /yquant/every initial label,% /yquant/every qubit label}% }% \endgroup% } \newif\ifyquant@register@get@allowmulti % converts names to indices % #1: comma-separated string of names or ranges % range format: startname-endname % Both startname and endname may be omitted, denoting the very first and last % register, respectively % If \ifyquant@register@get@allowmulti is set to true, multi-qubit registers are % allowed, which are surrounded by parentheses. They may not appear in ranges. % \yquant@register@get@ids@list, \yquant@register@get@ids@min, \yquant@register@get@ids@max and \yquant@register@get@ids@count will be set appropriately \begingroup% \catcode`[=\active% \catcode`(=\active% \protected\gdef\yquant@register@get@ids#1{% \begingroup% \let\yquant@register@get@ids@list=\empty% \count0=2147483647 % minimal id \count2=0 % maximal id \count4=0 % number of total registers \ifblank{#1}{}{% \let\ifinmulti=\iffalse% \let\ifallowmain=\iffalse% \let\do=\yquant@register@get@ids@outerlist% \begingroup% \catcode`[=\active% \catcode`(=\active% \def[##1]{\yquant@register@get@ids@@index{##1}}% \def(##1){\yquant@register@get@ids@@multi{##1}}% % this is also invoked by other languages which might have completely redefined all catcodes (qasm redefines the backslash), so don't just add \noexpand at the end of the \scantokens... \everyeof{\noexpand}% \endlinechar=-1 % \edef\yquant@register@get@ids@retokenized{\scantokens{#1}}% \expandafter% \endgroup% \expandafter\docsvlist\expandafter{\yquant@register@get@ids@retokenized}% }% \global\let\yquant@register@get@ids@list=\yquant@register@get@ids@list% \xdef\yquant@register@get@ids@min{\the\count0}% \xdef\yquant@register@get@ids@max{\the\count2}% \xdef\yquant@register@get@ids@count{\the\count4}% \endgroup% } \endgroup \let\yquant@register@get@ids@@index=\yquant@protectedempty \let\yquant@register@get@ids@@multi=\yquant@protectedempty \def\yquant@register@get@ids@outerlist#1{% \ifyquant@firsttoken\yquant@register@get@ids@@multi{#1}{% \unless\ifyquant@register@get@allowmulti% \PackageError{yquant.sty}{Multi-register gate not allowed}% {The selected gate can only be used in a single-register context.}% \fi% \yquant@register@get@ids@multi#1\yquant@sep% }{% \yquant@register@get@ids@checkrange#1-\yquant@sep% }% } \protected\def\yquant@register@get@ids@multi\yquant@register@get@ids@@multi#1\yquant@sep{% \begingroup% \let\yquant@register@get@ids@list=\empty% \count0=2147483647 % minimal id \count2=0 % maximal id \count4=0 % number of total registers \count6=-1 % index of main register \let\ifinmulti=\iftrue% \let\ifallowmain=\iftrue% \let\do=\yquant@register@get@ids@multilist% \docsvlist{#1}% \ifnum\count6=-1 % \count6=\count0 % \fi% \yquant@register@multi@splitparts% \edef\process{% \endgroup% \noexpand\listadd\noexpand\yquant@register@get@ids@list{% \noexpand\yquant@register@multi% {\the\count0}{\the\count2}{\the\count4}% {\yquant@register@get@ids@list}% }% \noexpand\ifnum\count0>\the\count0\space% \count0=\the\count0\space% \noexpand\fi% \noexpand\ifnum\count2<\the\count2\space% \count2=\the\count2\space% \noexpand\fi% \advance\count4 by 1 % }% \process% } \def\yquant@register@get@ids@multilist#1{% \yquant@register@get@ids@checkrange#1-\yquant@sep% } \def\yquant@register@get@ids@checkrange#1-#2\yquant@sep{% \ifstrempty{#2}{% % the string does not contain a dash \yquant@register@get@ids@norange{#1}% }{% % this is a range argument \yquant@register@get@ids@range#1-#2\yquant@sep% }% } \def\yquant@register@get@ids@norange#1{% % the register is not used within a range, which gives us full freedom with respect to sub-index selections \yquant@register@get@ids@norange@checkindex% #1% \yquant@register@get@ids@@index% \yquant@sep% } \protected\def\yquant@register@get@ids@norange@checkindex#1\yquant@register@get@ids@@index#2\yquant@sep{% \edef\current{\trim@spaces{#1}}% \ifallowmain% \expandafter\ifyquant@firsttoken\expandafter*\expandafter{\current}{% \edef\current{% \expandafter\expandafter\expandafter\trim@spaces% \expandafter\expandafter\expandafter{% \expandafter\@gobble\current% }% }% % catch the minimal index \edef\yquant@register@get@ids@norange@checkindex@setmain{% \count6=\count2% \ifnum\count0<\the\count0 % \count0=\the\count0 % \fi% }% \count0=2147483647 % \csletcs{ifallowmain}{iffalse}% }{% \let\yquant@register@get@ids@norange@checkindex@setmain=\relax% }% \else% \let\yquant@register@get@ids@norange@checkindex@setmain=\relax% \fi% \ifstrempty{#2}{% % the string does not contain a sub-index; we add the full register \yquant@register@get@id\first{\current[0]}% \letcs\high{\yquant@prefix registerhigh@\current}% \yquant@register@get@id\last{\current[\high]}% \ifnum\first<\count0 % \count0=\first\relax% \fi% \ifnum\last>\count2 % \count2=\last\relax% \fi% \advance\count4 by \numexpr\high+1\relax% \yquant@for \i := 0 to \high {% \yquant@register@get@id\idx{\current[\i]}% \listeadd\yquant@register@get@ids@list{\idx}% }% }{% \yquant@register@get@ids@norange@index#2% }% \yquant@register@get@ids@norange@checkindex@setmain% } \protected\def\yquant@register@get@ids@norange@index#1\yquant@register@get@ids@@index{% \let\olddo=\do% % the string contains sub-indices; since we are not in a range, multi-indices may still be allowed \ifinmulti% \let\do=\yquant@register@get@ids@subindex@nomulti% \else% \let\do=\yquant@register@get@ids@subindex@allowmulti% \fi% \docsvlist{#1}% \let\do=\olddo% } \def\yquant@register@get@ids@subindex@nomulti#1{% \yquant@register@get@ids@subindex@checkrange#1-\yquant@sep% } \def\yquant@register@get@ids@subindex@allowmulti#1{% \ifyquant@firsttoken\yquant@register@get@ids@@multi{#1}{% \unless\ifyquant@register@get@allowmulti% \PackageError{yquant.sty}{Multi-register gate not allowed}% {The selected gate can only be used in a single-register context.}% \fi% \yquant@register@get@ids@subindex@multi#1\yquant@sep% }{% \yquant@register@get@ids@subindex@checkrange#1-\yquant@sep% }% } \protected\def\yquant@register@get@ids@subindex@multi\yquant@register@get@ids@@multi#1\yquant@sep{% \begingroup% \let\yquant@register@get@ids@list=\empty% \count0=2147483647 % minimal id \count2=0 % maximal id \count4=0 % number of total registers \count6=-1 % index of main register \let\ifinmulti=\iftrue% \let\ifallowmain=\iftrue% \let\do=\yquant@register@get@ids@subindex@nomulti% \docsvlist{#1}% \ifnum\count6=-1 % \count6=\count0 % \fi% \yquant@register@multi@splitparts% \edef\process{% \endgroup% \noexpand\listadd\noexpand\yquant@register@get@ids@list{% \noexpand\yquant@register@multi% {\the\count0}{\the\count2}{\the\count4}% {\yquant@register@get@ids@list}% }% \noexpand\ifnum\count0>\the\count0\space% \count0=\the\count0\space% \noexpand\fi% \noexpand\ifnum\count2<\the\count2\space% \count2=\the\count2\space% \noexpand\fi% \advance\count4 by 1 % }% \process% } \def\yquant@register@get@ids@subindex@checkrange#1-#2\yquant@sep{% \ifstrempty{#2}{% % the string does not contain a dash, this is a single sub-item \edef\idx{\trim@spaces{#1}}% \expandafter\yquant@register@get@ids@subindex@norange\expandafter{\idx}% }{% % this is a range argument \yquant@register@get@ids@subindex@range#1-#2\yquant@sep% }% } \protected\def\yquant@register@get@ids@subindex@norange#1{% \ifallowmain%% \ifyquant@firsttoken*{#1}{% \edef\idx{\current[\expandafter\trim@spaces\expandafter{\@gobble#1}]}% \expandafter\yquant@register@get@id\expandafter\idx\expandafter{\idx}% \count6=\idx% \csletcs{ifallowmain}{iffalse}% }{% \yquant@register@get@id\idx{\current[#1]}% }% \else% \yquant@register@get@id\idx{\current[#1]}% \fi% \ifnum\idx<\count0 % \count0=\idx\relax% \fi% \ifnum\idx>\count2 % \count2=\idx\relax% \fi% \advance\count4 by 1\relax% \listeadd\yquant@register@get@ids@list{\idx}% } \protected\def\yquant@register@get@ids@subindex@range#1-#2-\yquant@sep{% \ifallowmain% \ifyquant@firsttoken*{#1}{% \expandafter\ifblank\expandafter{\@gobble#1}{% \def\first{0}% }{% \expandafter\yquant@langhelper@validate\expandafter\first\expandafter\count\expandafter{\@gobble#1}% }% \yquant@register@get@id\idx{\current[\first]}% \count6=\idx% \csletcs{ifallowmain}{iffalse}% }{% \ifblank{#1}{% \def\first{0}% }{% \yquant@langhelper@validate\first\count{#1}% }% }% \else% \ifblank{#1}{% \def\first{0}% }{% \yquant@langhelper@validate\first\count{#1}% }% \fi% \ifallowmain% % in #1, all initial spaces are gobbled automatically, but not in #2 \expandafter\ifyquant@firsttoken\expandafter*\expandafter{\empty#2}{% \expandafter\ifblank\expandafter{\@gobble#2}{% \yquant@register@get@id@high\last\current% }{% \expandafter\yquant@langhelper@validate\expandafter\last\expandafter\count\expandafter{\@gobble#2}% }% \yquant@register@get@id\idx{\current[\last]}% \count6=\idx% \csletcs{ifallowmain}{iffalse}% }{% \ifblank{#2}{% \yquant@register@get@id@high\last\current% }{% \yquant@langhelper@validate\last\count{#2}% }% }% \else% \ifblank{#2}{% \yquant@register@get@id@high\last\current% }{% \yquant@langhelper@validate\last\count{#2}% }% \fi% \yquant@for \i := \first to \last {% \yquant@register@get@ids@subindex@norange\i% }% } \protected\def\yquant@register@get@ids@range#1-#2-\yquant@sep{% % being a range between two registers, those must be uniquely identifiable, i.e. either a single sub-indexed part of a vector register, or no vector specification at all. \ifallowmain% \ifyquant@firsttoken*{#1}{% \expandafter\ifblank\expandafter{\@gobble#1}{% \def\first{1}% }{% \expandafter\yquant@register@get@ids@range@getfirst\@gobble#1\yquant@register@get@ids@@index\yquant@sep% }% \count6=\first% \csletcs{ifallowmain}{iffalse}% }{% \ifblank{#1}{% \def\first{1}% }{% \yquant@register@get@ids@range@getfirst#1\yquant@register@get@ids@@index\yquant@sep% }% }% \else% \ifblank{#1}{% \def\first{1}% }{% \yquant@register@get@ids@range@getfirst#1\yquant@register@get@ids@@index\yquant@sep% }% \fi% % it does not make sense to allow to set the main part on the second half of the range, since a range over registers (not indices) is automatically visual, so this range will be contiguous. \ifblank{#2}{% \letcs\last{\yquant@prefix registers}% }{% \yquant@register@get@ids@range@getlast#2\yquant@register@get@ids@@index\yquant@sep% }% \ifnum\first<\last\relax% \ifnum\first<\count0 % \count0=\first\relax% \fi% \ifnum\last>\count2 % \count2=\last\relax% \fi% \advance\count4 by \numexpr\last-\first+1\relax% \else% \ifnum\last<\count0 % \count0=\last\relax% \fi% \ifnum\first>\count2 % \count2=\first\relax% \fi% \advance\count4 by \numexpr\first-\last+1\relax% \fi% \yquant@for \i := \first to \last {% \listeadd\yquant@register@get@ids@list{\i}% }% } \def\yquant@register@get@ids@range@getfirst#1\yquant@register@get@ids@@index#2\yquant@sep{% \ifstrempty{#2}{% \yquant@register@get@id\first{\trim@spaces{#1}[0]}% }{% \yquant@register@get@ids@range@get\first#1\yquant@register@get@ids@@index#2% }% } \protected\def\yquant@register@get@ids@range@getlast#1\yquant@register@get@ids@@index#2\yquant@sep{% \ifstrempty{#2}{% \yquant@register@get@id@high\last{\trim@spaces{#1}}% \yquant@register@get@id\last{\trim@spaces{#1}[\last]}% }{% \yquant@register@get@ids@range@get\last#1\yquant@register@get@ids@@index#2% }% } \def\yquant@register@get@ids@range@get#1#2\yquant@register@get@ids@@index#3\yquant@register@get@ids@@index{% \yquant@register@get@id#1{\trim@spaces{#2}[\trim@spaces{\trim@spaces#3}]}% } \let\yquant@register@multi=\empty \let\yquant@register@multi@contiguous=\yquant@protectedempty % splits \yquant@register@get@ids@list into a list of contiguous parts \protected\def\yquant@register@multi@splitparts{% \begingroup% \let\registers=\yquant@register@get@ids@list% \yquant@sort@list\registers\yquant@sort@ascending% \let\newlist=\empty% \count2=-1 % \def\do##1{% \ifnum\count2=-1 % \count2=##1 % \count4=\count2 % \else% \advance\count2 by 1 % \ifnum##1>\count2 % % this is a discontiguous change (we disallow duplicate entries) \eappto\newlist{% \yquant@register@multi@contiguous% {\the\count4}{\the\numexpr\count2-1\relax}% {\ifnum\count6<\count2 % \ifnum\count4>\count6 % 0% \else% 1% \fi% \else% 0% \fi}% }% \count2=##1 % \count4=\count2 % \fi% \fi% }% \dolistloop\registers% % we disallow empty lists \eappto\newlist{% \yquant@register@multi@contiguous% {\the\count4}{\the\count2}% {\ifnum\count6>\count2 % 0% \else% \ifnum\count4>\count6 % 0% \else% 1% \fi% \fi}% }% \expandafter% \endgroup% \expandafter\def\expandafter\yquant@register@get@ids@list\expandafter{% \newlist% }% } % splits \yquant@register@get@ids@list into a list of discontiguous parts \protected\def\yquant@register@multi@splitparts@sepall{% \begingroup% \let\registers=\yquant@register@get@ids@list% \yquant@sort@list\registers\yquant@sort@ascending% \let\newlist=\empty% \def\do##1{% \eappto\newlist{% \yquant@register@multi@contiguous% {##1}{##1}% {\ifnum##1=\count6 % 1% \else% 0% \fi% }% }% }% \dolistloop\registers% \expandafter% \endgroup% \expandafter\def\expandafter\yquant@register@get@ids@list\expandafter{% \newlist% }% } \protected\def\yquant@register@multi@splitparts@sort{% \yquant@sort@list\yquant@register@get@ids@list\yquant@sort@ascending% } \protected\def\yquant@register@get@multiassingle{% \yquant@register@get@allowmultitrue% \let\yquant@register@multi@splitparts=\yquant@register@multi@splitparts@sepall% \preto\yquant@attrs@remaining{/yquant/operator/multi as single,}% } \protected\def\yquant@register@get@multiaslist{% \yquant@register@get@allowmultitrue% \let\yquant@register@multi@splitparts=\yquant@register@multi@splitparts@sort% } \let\yquant@register@multi@reset@original@splitparts=\yquant@register@multi@splitparts% \protected\def\yquant@register@reset@multi{% % \yquant@register@get@allowmultifalse% not needed, as \yquant@circuit@operator automatically resets it \let\yquant@register@multi@splitparts=\yquant@register@multi@reset@original@splitparts% } % converts a single name to an index (no lazy creation) % #1: where to store the index % #2: register name % #3: 0 or 2 if a vector register without brackets refers to the first index % 1 or 3 if it refers to the last % If #3 is 2 or 3, then the macro will, after execution, be \@firstoftwo if a vector register % was specified and \@secondoftwo if an explicit index was given. Else, the macro will vanish. % If the register does not exist, #1 is made undefined \protected\def\yquant@register@singleget#1#2{% \yquant@register@singleget@i\yquant@prefix#2[\yquant@sep{#1}% } % does the same for another circuit (id in #2) \protected\def\yquant@register@singlepeek#1#2#3{% \yquant@register@singleget@i{yquant@env#2@}#3[\yquant@sep{#1} } \def\yquant@register@singleget@i#1#2[#3\yquant@sep{% \ifstrempty{#3}{% \yquant@register@singleget@vector{#1}{#2}% }{% \yquant@register@singleget@indexed{#1}#2[#3\yquant@sep% }% } \protected\def\yquant@register@singleget@vector#1#2#3#4{% \ifcsname#1registername@\trim@spaces{#2}[0]\endcsname% \ifyquant@OR\ifnum0=#4 \fi\ifnum2=#4 \fi{% \letcs#3{#1registername@\trim@spaces{#2}[0]}% }{% \letcs#3{#1registername@\trim@spaces{#2}[\csname#1registerhigh@\trim@spaces{#2}\endcsname]}% }% \else% \undef#3% \fi% \ifnum1<#4 % \expandafter\@firstoftwo% \fi% } \protected\def\yquant@register@singleget@indexed#1#2[#3][\yquant@sep#4#5{% \ifcsname#1registername@\trim@spaces{#2}[\trim@spaces{#3}]\endcsname% \letcs#4{#1registername@\trim@spaces{#2}[\trim@spaces{#3}]}% \else% \undef#4% \fi% \ifnum1<#5 % \expandafter\@secondoftwo% \fi% } % END_FOLD % BEGIN_FOLD Getters: extract the requested information from the register with given id \def\yquant@register@get@type#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@type@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@type@aux\csname\yquant@prefix register@#1\endcsname% \fi% } \def\yquant@register@get@parent#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@type@aux\csname\yquant@prefix register@#1\endcsname% \else% \PackageError{yquant.sty}{Internal inconsistency detected}% {Tried to get parent of a non-connected wire.}% \fi% } \def\yquant@register@get@type@aux#1#2#3#4#5#6{#1} \def\yquant@register@get@x#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@x@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@x@aux\csname\yquant@prefix register@#1\endcsname% \fi% } \def\yquant@register@peek@x#1#2{% \ifcsname yquant@env#1@registermap@#2\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@x@aux\csname\csname yquant@env#1@registermap@#2\endcsname\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@x@aux\csname yquant@env#1@register@#2\endcsname% \fi% } \def\yquant@register@get@x@aux#1#2#3#4#5#6{#2} \def\yquant@register@get@height#1{% \expandafter\expandafter\expandafter% \yquant@register@get@height@aux\csname\yquant@prefix register@#1\endcsname% } \def\yquant@register@peek@height#1#2{% \expandafter\expandafter\expandafter% \yquant@register@get@height@aux\csname yquant@env#1@register@#2\endcsname% } \def\yquant@register@get@height@aux#1#2#3#4#5#6{\@firstofthree#3} \def\yquant@register@get@depth#1{% \expandafter\expandafter\expandafter% \yquant@register@get@depth@aux\csname\yquant@prefix register@#1\endcsname% } \def\yquant@register@peek@depth#1#2{% \expandafter\expandafter\expandafter% \yquant@register@get@depth@aux\csname yquant@env#1@register@#2\endcsname% } \def\yquant@register@get@depth@aux#1#2#3#4#5#6{\@secondofthree#3} \def\yquant@register@get@multispace#1{% \expandafter\expandafter\expandafter% \yquant@register@get@multispace@aux\csname\yquant@prefix register@#1\endcsname% } \def\yquant@register@get@multispace@aux#1#2#3#4#5#6{\@thirdofthree#3} % The y parameter get macros exist in two forms: The protected one is used during the storage to the draw macro; it should never be executed. The env environment then maps them to their proper expandable forms. \protected\def\yquant@register@get@y{% \PackageError% {yquant.sty}% {Execution of a get-y macro in an illegal context}% {get-y macros may not be called unless the yquant environment ends.}% } \protected\def\yquant@register@peek@y{% \PackageError% {yquant.sty}% {Execution of a peek-y macro in an illegal context}% {peek-y macros may not be called unless the yquant environment ends.}% } % This plays a similar role: It must never be expanded before the tikz command is invoked (because it does not exist). \let\nodepart=\yquant@protectedempty \def\yquant@register@get@y@unprotected#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@y@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@y@aux\csname\yquant@prefix register@#1\endcsname% \fi% } \def\yquant@register@peek@y@unprotected#1#2{% \ifcsname yquant@env#1@registermap@#2\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@y@aux\csname\csname yquant@env#1@registermap@#2\endcsname\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@y@aux\csname yquant@env#1@register@#2\endcsname% \fi% } \def\yquant@register@get@y@aux#1#2#3#4#5#6{#3} % y distance between two registers. \def\yquant@register@get@ydist#1#2{% \expandafter\yquant@abs\expandafter% {\the\dimexpr\yquant@register@get@y{#2}-\yquant@register@get@y{#1}\relax}% } \protected\def\yquant@register@get@y@@expandable{% \let\yquant@register@get@y=\yquant@register@get@y@unprotected% \let\yquant@register@peek@y=\yquant@register@peek@y@unprotected% } \def\yquant@register@get@lastwire#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\expandafter\expandafter% \yquant@register@get@lastwire@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\expandafter\expandafter% \yquant@register@get@lastwire@aux\csname\yquant@prefix register@#1\endcsname% }% } \protected\def\yquant@register@get@lastwire@aux#1#2#3#4#5#6#7{% \def#7{#4}% } \def\yquant@register@get@style#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@style@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@style@aux\csname\yquant@prefix register@#1\endcsname% \fi% } \def\yquant@register@get@style@aux#1#2#3#4#5#6{#5} \protected\long\def\yquant@register@execclear@lastgate#1#2{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter% \yquant@register@execclear@lastgate@aux@i\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname{#1}{#2}% \else% \expandafter% \yquant@register@execclear@lastgate@aux@i\csname\yquant@prefix register@#1\endcsname{#1}{#2}% \fi% } \def\yquant@register@execclear@lastgate@aux@i#1{% \expandafter\yquant@register@execclear@lastgate@aux@ii#1#1% } \long\def\yquant@register@execclear@lastgate@aux@ii#1#2#3#4#5#6#7#8#9{% \ifstrempty{#6}\relax{% #6{#8}{#9}% \xdef#7{\unexpanded{{#1}{#2}{#3}{#4}{#5}{}}}% }% } \def\yquant@register@get@typeywire#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\expandafter\expandafter% \yquant@register@get@typeywire@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\expandafter\expandafter% \yquant@register@get@typeywire@aux\csname\yquant@prefix register@#1\endcsname% }% } \protected\def\yquant@register@get@typeywire@aux#1#2#3#4#5#6#7#8#9{% \def#7{#1}% \def#8{#3}% \def#9{#4}% }% % Set #1 to the maximum x (vertical: minimum y) value found between #2 and #3 \protected\def\yquant@register@get@maxxrange#1#2#3{% \begingroup% \dimen0=\yquant@orientation@minus16383.99999pt % \yquant@for \yquant@register@get@maxx@i := #2 to #3 {% \dimen2=\yquant@register@get@x{\yquant@register@get@maxx@i}\relax% \ifdim\yquant@orientation@plus\dimen0<\yquant@orientation@plus\dimen2 % \dimen0=\dimen2 % \fi% }% \expandafter% \endgroup% \expandafter\def\expandafter#1\expandafter{\the\dimen0}% } % Set #1 to the maximum x (vertical: minimum y) value found in the list #2 \protected\def\yquant@register@get@maxxlist@i#1{% \dimen2=\yquant@register@get@x{#1}\space% \ifdim\yquant@orientation@plus\dimen0<\yquant@orientation@plus\dimen2 % \dimen0=\dimen2 % \fi% } \protected\def\yquant@register@get@maxxlist#1#2{% \begingroup% \dimen0=\yquant@orientation@minus16383.99999pt % \forlistloop\yquant@register@get@maxxlist@i{#2}% \expandafter% \endgroup% \expandafter\def\expandafter#1\expandafter{\the\dimen0}% } \protected\def\yquant@register@peek@maxxlist@i#1#2{% \dimen2=\expandafter\yquant@register@peek@x{#1}{#2}\space% \ifdim\yquant@orientation@plus\dimen0<\yquant@orientation@plus\dimen2 % \dimen0=\dimen2 % \fi% } \protected\def\yquant@register@peek@maxxlist#1#2{% \begingroup% \dimen0=\yquant@orientation@minus16383.99999pt % \forlistloop{\yquant@register@colonsplit\yquant@register@peek@maxxlist@i}{#2}% \expandafter% \endgroup% \expandafter\def\expandafter#1\expandafter{\the\dimen0}% } \protected\def\yquant@register@flag@clean@enclose#1#2{% % the register was clean when we visited it; so just treat it as already visited in the enclose to not destroy the movelabel \expandafter\ifx\csname yquant@circuit@enclose@#2@involved\endcsname\yquant@circuit@enclose@allinvolved% \edef\curcolon{\yquant@register@resolvetocolon{#1}}% \xifinlistcs\curcolon{yquant@circuit@enclose@#2@visited}\relax{% \listcsxadd{yquant@circuit@enclose@#2@visited}\curcolon% }% \else% \ifyquant@circuit@enclose@relevant{#2}{#1}{% \edef\curcolon{\yquant@register@resolvetocolon{#1}}% \ifnum\csname yquant@circuit@enclose@#2@spacing\endcsname=0 % \xifinlist\curcolon{yquant@circuit@enclose@#2@involved}\relax{% \listcsxadd{yquant@circuit@enclose@#2@involved}\curcolon% }% \else% \unless\ifcsname yquant@circuit@enclose@#2@extentT@\curcolon\endcsname% \csgdef{yquant@circuit@enclose@#2@extentT@\curcolon}{0pt}% \global\csletcs{yquant@circuit@enclose@#2@extentB@\curcolon}{yquant@circuit@enclose@#2@extentT@\curcolon}% \listcsxadd{yquant@circuit@enclose@#2@involved}{\curcolon}% \fi% \fi% }% \fi% } \protected\def\yquant@register@flag@clean#1#2{% \ifstrequal{#2}{init}{% \advance\count8 by 1 % }\relax% \forlistloop{\yquant@register@flag@clean@enclose{#1}}\yquant@circuit@enclose@active% } % END_FOLD % BEGIN_FOLD Setters: change register information \protected\long\def\yquant@register@set@@aux#1#2#3{% \xdef#1{\expandafter#2#1{#3}}% } \protected\def\yquant@register@set@type#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@type@aux% } \long\def\yquant@register@set@type@aux#1#2#3#4#5#6#7{% {#7}\unexpanded{{#2}{#3}{#4}{#5}{#6}}% } \protected\def\yquant@register@set@x#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@x@aux% } \long\def\yquant@register@set@x@aux#1#2#3#4#5#6#7{% \unexpanded{{#1}}{#7}\unexpanded{{#3}{#4}{#5}{#6}}% } \protected\def\yquant@register@update@height#1#2{% \unless\ifyquant@lang@attr@overlay@height% \ifdim#2>% \expandafter\expandafter\expandafter% \yquant@register@get@height@aux\csname\yquant@prefix register@#1\endcsname% \relax% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% \yquant@register@set@height@aux{#2}% \fi% \fi% \yquant@circuit@enclose@update@extentTB T{#1}{#2}% } \protected\def\yquant@register@set@height@remote#1#2#3{% \expandafter\yquant@register@set@@aux% \csname yquant@env#1@register@#2\endcsname% \yquant@register@set@height@aux{#3}% } \long\def\yquant@register@set@height@aux#1#2#3#4#5#6#7{% \unexpanded{{#1}{#2}}% {{#7}% {\unexpanded\expandafter{\@secondofthree#3}}% {\unexpanded\expandafter{\@thirdofthree#3}}}% \unexpanded{{#4}{#5}{#6}}% } \protected\def\yquant@register@update@depth#1#2{% \unless\ifyquant@lang@attr@overlay@depth% \ifdim#2>% \expandafter\expandafter\expandafter% \yquant@register@get@depth@aux\csname\yquant@prefix register@#1\endcsname% \relax% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% \yquant@register@set@depth@aux{#2}% \fi% \fi% \yquant@circuit@enclose@update@extentTB B{#1}{#2}% } \protected\def\yquant@register@set@depth@remote#1#2#3{% \expandafter\yquant@register@set@@aux% \csname yquant@env#1@register@#2\endcsname% \yquant@register@set@depth@aux{#3}% } \long\def\yquant@register@set@depth@aux#1#2#3#4#5#6#7{% \unexpanded{{#1}{#2}}% {{\unexpanded\expandafter{\@firstofthree#3}}% {#7}% {\unexpanded\expandafter{\@thirdofthree#3}}}% \unexpanded{{#4}{#5}{#6}}% } \protected\def\yquant@register@update@multispace#1#2#3{% \unless\ifnum#1<#2 % \PackageError{yquant.sty}{Internal inconsistency detected}% {Setting multispace part in wrong order.}% \fi% \unless\ifyquant@lang@attr@overlay@multi% \begingroup% \edef\tmp{% \expandafter\expandafter\expandafter% \yquant@register@get@multispace@aux\csname\yquant@prefix register@#1\endcsname% }% \let\old=\tmp% \yquant@list@eupdateorinsert\tmp{#2}{#3}% \unless\ifx\old\tmp% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% \yquant@register@set@multispace@aux\tmp% \fi% \endgroup% \fi% \yquant@for \yquant@register@update@multispace@i := #1 to #2 {% % we don't know the size, but we have to register it \yquant@circuit@enclose@update@extentTB T{\yquant@register@update@multispace@i}{0pt}% } } \long\def\yquant@register@set@multispace@aux#1#2#3#4#5#6#7{% \unexpanded{{#1}{#2}}% {{\unexpanded\expandafter{\@firstofthree#3}}% {\unexpanded\expandafter{\@secondofthree#3}}% {#7}}% \unexpanded{{#4}{#5}{#6}}% } \protected\def\yquant@register@inject@extents#1#2{% % enlarge the last subcircuit that was created previously by height #1 and depth #2. % We enforce subcircuits to have registers, so no check needed. \expandafter\yquant@register@set@@aux% \csname yquant@env\the\yquant@env @register@1\endcsname% \yquant@register@inject@height@aux{#1}% \expandafter\yquant@register@set@@aux% \csname yquant@env\the\yquant@env @register@\csname yquant@env\the\yquant@env @registers\endcsname\endcsname% \yquant@register@inject@depth@aux{#2}% } \long\def\yquant@register@inject@height@aux#1#2#3#4#5#6#7{% \unexpanded{{#1}{#2}}% {{\the\dimexpr\@firstofthree#3+#7\relax}% {\unexpanded\expandafter{\@secondofthree#3}}% {\unexpanded\expandafter{\@thirdofthree#3}}}% \unexpanded{{#4}{#5}{#6}}% } \long\def\yquant@register@inject@depth@aux#1#2#3#4#5#6#7{% \unexpanded{{#1}{#2}}% {{\unexpanded\expandafter{\@firstofthree#3}}% {\the\dimexpr\@secondofthree#3+#7\relax}% {\unexpanded\expandafter{\@thirdofthree#3}}}% \unexpanded{{#4}{#5}{#6}}% } \protected\def\yquant@register@set@y#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@y@aux% } \long\def\yquant@register@set@y@aux#1#2#3#4#5#6#7{% \unexpanded{{#1}{#2}}{#7}\unexpanded{{#4}{#5}{#6}}% } \protected\def\yquant@register@set@lastwire#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@lastwire@aux% } \long\def\yquant@register@set@lastwire@aux#1#2#3#4#5#6#7{% \unexpanded{{#1}{#2}{#3}}{#7}\unexpanded{{#5}{#6}}% } \protected\def\yquant@register@set@typelastwire#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \PackageError{yquant.sty}{Internal inconsistency detected}% {Setting type and lastwire was requested for a subcircuit.}% \fi% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% \yquant@register@set@typelastwire@aux% } \long\def\yquant@register@set@typelastwire@aux#1#2#3#4#5#6#7{% {\@firstoftwo#7}\unexpanded{{#2}{#3}}{\@secondoftwo#7}\unexpanded{{#5}{#6}}% } \protected\def\yquant@register@set@style#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@style@aux% } \long\def\yquant@register@set@style@aux#1#2#3#4#5#6#7{% \unexpanded{{#1}{#2}{#3}{#4}}{#7}\unexpanded{{#6}}% } \protected\def\yquant@register@set@lastgate#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@lastgate@aux% } \long\def\yquant@register@set@lastgate@aux#1#2#3#4#5#6#7{% \unexpanded{{#1}{#2}{#3}{#4}{#5}}{#7}% } \long\def\yquant@register@set@typelastgate@aux#1#2#3#4#5#6#7{% {\@firstoftwo#7}\unexpanded{{#2}{#3}{#4}{#5}}{\@secondoftwo#7}% } % END_FOLD