निरंजन
I found [this][1] answer which I liked very much, but it only gives OR conditional. I want AND conditional **instead** of OR with similar mechanism¹. (I don't need OR at the moment.) Can it be done? See the following example.
```
\documentclass{article}
\newcounter{mycnta}
\newcounter{mycntb}
\def\checking{%
\ifnum
\ifnum
\value{mycnta}=1
1
\else
\ifnum
\value{mycntb}=14
1
\else
0
\fi
\fi
=1
true%
\else
false%
\fi
}
\begin{document}
\begin{enumerate}
\item
\setcounter{mycnta}{1}
\setcounter{mycntb}{14}
Should return true. Returns \checking .
\item
\setcounter{mycnta}{3}
\setcounter{mycntb}{15}
Should return false. Returns \checking .
\item
\setcounter{mycnta}{2}
\setcounter{mycntb}{14}
Should return false. Returns \checking .
\item
\setcounter{mycnta}{1}
\setcounter{mycntb}{15}
Should return false. Returns \checking .
\end{enumerate}
\end{document}
```
---
¹ i.e., preferably without `\expandafter`s because I don't understand what they do :joy:.
[1]: https://tex.stackexchange.com/a/29906/174620
Top Answer
Skillmon
The following is a simple method to get OR, AND, and XOR supported. Anything unequal to zero is interpreted as true, each `\if` returns either 0 (false) or 1 (true), then an AND is a multiplication, an OR is an addition, and a XOR is a subtraction.
This is combined in a `\numexpr` for a single `\ifnum` test (and this way fully expandable, your `\if`-tests must be fully expandable as well here).
I read you prefer without `\expandafter`s, but I included one to get the branching as arguments (`\expandafter` simply expands the `\fi` (expands to nothing, closing the `\ifnum`-block) before the `\@thirdofthree` so that the `\ifnum` is complete (if it was true), and `\@thirdofthree` sees as its arguments `\@firstoftwo{<true>}{<false>}` picking up `<false>`).
The code for AND and OR scale to arbitrary many relations this way, XOR on the other hand doesn't.
```
\documentclass{article}
\newcounter{mycnta}
\newcounter{mycntb}
\makeatletter
\providecommand\@thirdofthree[3]{#3}
\newcommand\checking[1]
{%
\ifnum0=\numexpr
\ifnum\value{mycnta}=1 1\else0\fi
#1\ifnum\value{mycntb}=14 1\else0\fi
\relax
\expandafter\@thirdofthree
\fi
\@firstoftwo
}
\makeatother
\newcommand\checkingAND
{%
\checking{*}%
{true}
{false}%
}
\newcommand\checkingOR
{%
\checking{+}%
{true}
{false}%
}
\newcommand\checkingXOR
{%
\checking{-}%
{true}
{false}%
}
\begin{document}
\begin{enumerate}
\item
\setcounter{mycnta}{1}
\setcounter{mycntb}{14}
AND should return true. Returns \checkingAND.\\
OR should return true. Returns \checkingOR.\\
XOR should return false. Returns \checkingXOR.
\item
\setcounter{mycnta}{3}
\setcounter{mycntb}{15}
AND should return false. Returns \checkingAND.\\
OR should return false. Returns \checkingOR.\\
XOR should return false. Returns \checkingXOR.
\item
\setcounter{mycnta}{2}
\setcounter{mycntb}{14}
AND should return false. Returns \checkingAND.\\
OR should return true. Returns \checkingOR.\\
XOR should return true. Returns \checkingXOR.
\item
\setcounter{mycnta}{1}
\setcounter{mycntb}{15}
AND should return false. Returns \checkingAND.\\
OR should return true. Returns \checkingOR.\\
XOR should return true. Returns \checkingXOR.
\end{enumerate}
\end{document}
```
---
Because Joseph kind-of challenged me, the following implements AND, OR, and XOR without using `\numexpr`, unfortunately we need a bit more variety in our `\checking` macro from above, hence the following has a bit more code to achieve the same with a bit better performance. The AND and OR relations are implemented lazy (meaning the second conditional is only evaluated if the result isn't clear after the first).
```
\documentclass{article}
\newcounter{mycnta}
\newcounter{mycntb}
\makeatletter
\providecommand\@thirdofthree[3]{#3}
\newcommand\checkingAND
{%
\ifnum\ifnum\value{mycnta}=1 \ifnum\value{mycntb}=14 1\else0\fi\else0\fi=0
\expandafter\@thirdofthree
\fi
\@firstoftwo
{true}{false}%
}
\newcommand\checkingOR
{%
\ifnum\ifnum\value{mycnta}=1 1\else\ifnum\value{mycntb}=14 1\else0\fi\fi=0
\expandafter\@thirdofthree
\fi
\@firstoftwo
{true}{false}%
}
\newcommand\checkingXOR
{%
\ifnum\ifnum\value{mycnta}=1 1\else0\fi=\ifnum\value{mycntb}=14 1\else0\fi\space
\expandafter\@thirdofthree
\fi
\@firstoftwo
{true}{false}%
}
\makeatother
\begin{document}
\begin{enumerate}
\item
\setcounter{mycnta}{1}
\setcounter{mycntb}{14}
AND should return true. Returns \checkingAND.\\
OR should return true. Returns \checkingOR.\\
XOR should return false. Returns \checkingXOR.
\item
\setcounter{mycnta}{3}
\setcounter{mycntb}{15}
AND should return false. Returns \checkingAND.\\
OR should return false. Returns \checkingOR.\\
XOR should return false. Returns \checkingXOR.
\item
\setcounter{mycnta}{2}
\setcounter{mycntb}{14}
AND should return false. Returns \checkingAND.\\
OR should return true. Returns \checkingOR.\\
XOR should return true. Returns \checkingXOR.
\item
\setcounter{mycnta}{1}
\setcounter{mycntb}{15}
AND should return false. Returns \checkingAND.\\
OR should return true. Returns \checkingOR.\\
XOR should return true. Returns \checkingXOR.
\end{enumerate}
\end{document}
```
```
Answer #2
frougon
Not directly using primitives, but I think this may be useful.
Here are two ways with `expl3`. All these macros are expandable.
# Naive way
```
\documentclass{article}
\ExplSyntaxOn
\cs_new:Npn \my_and:nnTF #1#2
{
\bool_lazy_and:nnTF % we didn't grab the T and F args
{ \int_compare_p:nNn { \value{mycnta} } = {#1} }
{ \int_compare_p:nNn { \value{mycntb} } = {#2} }
}
\cs_new:Npn \my_or:nnTF #1#2
{
\bool_lazy_or:nnTF % we didn't grab the T and F args
{ \int_compare_p:nNn { \value{mycnta} } = {#1} }
{ \int_compare_p:nNn { \value{mycntb} } = {#2} }
}
\cs_new:Npn \my_xor:nnTF #1#2
{
\bool_xor:nnTF % we didn't grab the T and F args
{ \int_compare_p:nNn { \value{mycnta} } = {#1} }
{ \int_compare_p:nNn { \value{mycntb} } = {#2} }
}
\cs_new_eq:NN \myAnd \my_and:nnTF
\cs_new_eq:NN \myOr \my_or:nnTF
\cs_new_eq:NN \myXor \my_xor:nnTF
\ExplSyntaxOff
\newcounter{mycnta}
\newcounter{mycntb}
\begin{document}
\setcounter{mycnta}{1}
\setcounter{mycntb}{14}
\noindent
\myAnd{1}{14}{true}{false}\\
\myAnd{2}{14}{true}{false}\\
\myAnd{1}{12}{true}{false}\\
\myAnd{2}{12}{true}{false}
\medskip\noindent
\myOr{1}{14}{true}{false}\\
\myOr{2}{14}{true}{false}\\
\myOr{1}{12}{true}{false}\\
\myOr{2}{12}{true}{false}
\medskip\noindent
\myXor{1}{14}{true}{false}\\
\myXor{2}{14}{true}{false}\\
\myXor{1}{12}{true}{false}\\
\myXor{2}{12}{true}{false}
\end{document}
```
![image.png](/image?hash=5efbb21c3be67f7235eea53f11a73810ec53e65ff4d9dc2ad8902701e991ffe4)
# Better way (more flexible)
This way generates the predicate forms (`\my_and_p:nn`, `\my_or_p:nn` and `\my_xor_p:nn`) as well as all variants:
- `\my_and:nnT`, `\my_and:nnF` and `\my_and:nnTF`;
- `\my_or:nnT`, `\my_or:nnF` and `\my_or:nnTF`;
- `\my_xor:nnT`, `\my_xor:nnF` and `\my_xor:nnTF`.
```
\documentclass{article}
\usepackage[table]{xcolor}
\ExplSyntaxOn
\prg_new_conditional:Npnn \my_and:nn #1#2 { p, T, F, TF }
{
\bool_lazy_and:nnTF
{ \int_compare_p:nNn { \value{mycnta} } = {#1} }
{ \int_compare_p:nNn { \value{mycntb} } = {#2} }
{ \prg_return_true: }
{ \prg_return_false: }
}
\prg_new_conditional:Npnn \my_or:nn #1#2 { p, T, F, TF }
{
\bool_lazy_or:nnTF
{ \int_compare_p:nNn { \value{mycnta} } = {#1} }
{ \int_compare_p:nNn { \value{mycntb} } = {#2} }
{ \prg_return_true: }
{ \prg_return_false: }
}
\prg_new_conditional:Npnn \my_xor:nn #1#2 { p, T, F, TF }
{
\bool_xor:nnTF
{ \int_compare_p:nNn { \value{mycnta} } = {#1} }
{ \int_compare_p:nNn { \value{mycntb} } = {#2} }
{ \prg_return_true: }
{ \prg_return_false: }
}
\cs_new_eq:NN \myAndT \my_and:nnT
\cs_new_eq:NN \myAndF \my_and:nnF
\cs_new_eq:NN \myAndTF \my_and:nnTF
\cs_new_eq:NN \myOrTF \my_or:nnTF
\cs_new_eq:NN \myXorTF \my_xor:nnTF
\ExplSyntaxOff
\newcounter{mycnta}
\newcounter{mycntb}
\begin{document}
\setcounter{mycnta}{1}
\setcounter{mycntb}{14}
\noindent
\begin{tabular}{@{} *{3}{l} @{}}
\myAndTF{1}{14}{true}{false} & \myAndT{1}{14}{true} & \myAndF{1}{14}{false}\\
\myAndTF{2}{14}{true}{false} & \myAndT{2}{14}{true} & \myAndF{2}{14}{false}\\
\myAndTF{1}{12}{true}{false} & \myAndT{1}{12}{true} & \myAndF{1}{12}{false}\\
\myAndTF{2}{12}{true}{false} & \myAndT{2}{12}{true} & \myAndF{2}{12}{false}
\end{tabular}
\medskip\noindent
\myOrTF{1}{14}{true}{false}\\
\myOrTF{2}{14}{true}{false}\\
\myOrTF{1}{12}{true}{false}\\
\myOrTF{2}{12}{true}{false}
\medskip\noindent
\myXorTF{1}{14}{true}{false}\\
\myXorTF{2}{14}{true}{false}\\
\myXorTF{1}{12}{true}{false}\\
\myXorTF{2}{12}{true}{false}
\newcommand*{\conditionalStuff}[4]{%
\myXorTF{#1}{#2}
{\rowcolor{blue!40}#3}
{\rowcolor{red!40}#4}%
}
\medskip\noindent
\begin{tabular}{@{} l @{}}
\conditionalStuff{1}{14}{true}{false}\\
\conditionalStuff{2}{14}{true}{false}\\
\conditionalStuff{1}{12}{true}{false}\\
\conditionalStuff{2}{12}{true}{false}
\end{tabular}
\end{document}
```
![image.png](/image?hash=51c90ce086f52da6a33bf85f280387fc7ae30bb1b51424e4788109b4f7b58b3c)
Answer #3
निरंजन
I found one way :).
Don't know if it is optimal, would like to know thoughts on this.
```
\documentclass{article}
\newcounter{mycnta}
\newcounter{mycntb}
\newcounter{cntchecker}
\def\checking{%
\ifnum\value{mycnta}=1\relax
\addtocounter{cntchecker}{1}%
\fi
\ifnum
\value{mycntb}=14\relax
\addtocounter{cntchecker}{1}%
\fi
\ifnum\value{cntchecker}=2\relax
true%
\else
false%
\fi
\setcounter{cntchecker}{0}%
}
\begin{document}
\begin{enumerate}
\item
\setcounter{mycnta}{1}
\setcounter{mycntb}{14}
Should return true. Returns \checking .
\item
\setcounter{mycnta}{3}
\setcounter{mycntb}{15}
Should return false. Returns \checking .
\item
\setcounter{mycnta}{2}
\setcounter{mycntb}{14}
Should return false. Returns \checking .
\item
\setcounter{mycnta}{1}
\setcounter{mycntb}{15}
Should return false. Returns \checking .
\end{enumerate}
\end{document}
```