3

In the code below, what should the definition of \sumcounters be to make it sum the current values of the counters thm and lemma?

\documentclass{book}
\usepackage{amsthm}
\usepackage{xparse}
\newtheorem{thm}{Theorem}[chapter]
\newtheorem{lemma}{Lemma}[chapter]
\ExplSyntaxOn
\seq_new:N \g_my_counters
\seq_gput_right:Nn \g_my_counters { thm }
\seq_gput_right:Nn \g_my_counters { lemma }
% \NewDocumentCommand{\sumcounters}{}{< ? >}
\ExplSyntaxOff
\begin{document}
\chapter{Some chapter}
\sumcounters % should print 0

\begin{thm}
A theorem.
\end{thm}
\sumcounters % should print 1

\begin{lemma}
A lemma.
\end{lemma}
\sumcounters % should print 2
\end{document}

3 Answers 3

7

Instead of performing an assignment, you can also calculate the sum fully-expandably. This has the advantage that you can use it in conditionals, such as

\ifnum\sumcounters=0 ... \fi

I also want to remind you of the expl3 convention to use Hungarian notation for variables, i.e. a variable should carry in its name the data type it holds, usually as a suffix.

\documentclass{book}
\usepackage{amsthm}
\usepackage{xparse}
\newtheorem{thm}{Theorem}[chapter]
\newtheorem{lemma}{Lemma}[chapter]

\ExplSyntaxOn

\seq_new:N \g_my_counters_seq
\seq_gput_right:Nn \g_my_counters_seq { thm }
\seq_gput_right:Nn \g_my_counters_seq { lemma }

\cs_new:Npn \my_plus_value:n #1
  {
      + (\value{#1})
  }

\NewExpandableDocumentCommand \sumcounters { }
  {
    \int_eval:n
      {
        ( 0 \seq_map_function:NN \g_my_counters_seq \my_plus_value:n )
      }
  }

\ExplSyntaxOff

\begin{document}
\chapter{Some chapter}
\sumcounters % should print 0

\begin{thm}
A theorem.
\end{thm}
\sumcounters % should print 1

\begin{lemma}
A lemma.
\end{lemma}
\sumcounters % should print 2
\end{document}
2
  • +1 This is definitely the better solution. Is there any way to salvage my solution? I tried things like "returning" \int_eval:n \l_counter_sum_int and using \expandafter\ifnum\sumcounters ... without success. I would have thought it was possible to force expansion but nothing I tried worked.
    – user30471
    Commented May 1, 2019 at 7:58
  • 1
    @Andrew int_zero:N and \int_add:Nn are not expandable, so no. Commented May 1, 2019 at 8:37
4

You could probably do this with a temporary counter, such as \l_tmpa_int, but the code below defines a new counter \l_counter_sum_int and then the \sumcounters macro uses \seq_map_inline:Nn to add the current \values of the counters in \g_my_counters, after which it prints the result. The output is the expected:

enter image description here

Here is the full code:

\documentclass{book}
\usepackage{amsthm}
\usepackage{xparse}
\newtheorem{thm}{Theorem}[chapter]
\newtheorem{lemma}{Lemma}[chapter]
\ExplSyntaxOn
\seq_new:N \g_my_counters
\seq_gput_right:Nn \g_my_counters { thm }
\seq_gput_right:Nn \g_my_counters { lemma }
\int_new:N \l_counter_sum_int% local counter for adding counter values
\NewDocumentCommand\sumcounters{}{
  \int_zero:N \l_counter_sum_int% set \l_counter_sum_int to 0
  \seq_map_inline:Nn \g_my_counters {% add counters in \g_my_counters
     \int_add:Nn \l_counter_sum_int {\value{##1}}
  }
  \int_use:N \l_counter_sum_int% print the result
}
\ExplSyntaxOff
\begin{document}
\chapter{Some chapter}
\sumcounters % should print 0

\begin{thm}
A theorem.
\end{thm}
\sumcounters % should print 1

\begin{lemma}
A lemma.
\end{lemma}
\sumcounters % should print 2
\end{document}
4
  • Does it make a difference if I put \int_new:N \l_counter_sum_int inside the definition of \sumcounters?
    – noibe
    Commented May 1, 2019 at 2:27
  • @noibe Yes, it makes a difference: the code above will give an error because the second and subsequent calls of \sumcounters will try to define a define a counter that already exists. Alternatively, as I suggested, you can instead use \l_tmpa_int in \sumcounters, in which case you can drop the \int_new:N command completely. (I just checked and this works.)
    – user30471
    Commented May 1, 2019 at 2:28
  • If instead of directly using \sumcounters I type \ifnum\sumcounters=0 yes \else no \fi I get some unexpected results, while I'de expect a yes and two no's. What am I doing wrong?
    – noibe
    Commented May 1, 2019 at 2:42
  • @noibe As Henri says, this is an expansion issue. I didn't know you would want to use \sumcounters this way. I don't see an easy way to make my code work, so Henri's expandable solution is the way to go.
    – user30471
    Commented May 1, 2019 at 4:40
1

You can store \value{...} in the sequence and finally use the sequence.

\documentclass{book}
\usepackage{amsthm}
\usepackage{xparse}
\newtheorem{thm}{Theorem}[chapter]
\newtheorem{lemma}{Lemma}[chapter]

\ExplSyntaxOn

\NewDocumentCommand{\definesummation}{mm}
 {
  \seq_new:c { g_noibe_summation_#1_seq }
  \clist_map_inline:nn { #2 }
   {
    \seq_gput_right:cn { g_noibe_summation_#1_seq } { \value{##1} }
   }
  \cs_new:cpn { #1 }
   {
    \int_eval:n { \seq_use:cn { g_noibe_summation_#1_seq } { + } }
   }
 }

\ExplSyntaxOff

\definesummation{sumstatements}{thm,lemma}

\begin{document}

\chapter{Some chapter}
\sumstatements % should print 0

\begin{thm}
A theorem.
\end{thm}

\sumstatements % should print 1

\begin{lemma}
A lemma.
\end{lemma}

\sumstatements % should print 2

\end{document}

enter image description here

The same with xassoccnt.

\documentclass{book}
\usepackage{amsthm}
\usepackage{xassoccnt}

\newtheorem{thm}{Theorem}[chapter]
\newtheorem{lemma}{Lemma}[chapter]

\newcounter{totaltheorems}
\DeclareAssociatedCounters{thm}{totaltheorems}
\DeclareAssociatedCounters{lemma}{totaltheorems}

\begin{document}
\chapter{Some chapter}

\thetotaltheorems

\begin{thm}
A theorem.
\end{thm}

\thetotaltheorems

\begin{lemma}
A lemma.
\end{lemma}

\thetotaltheorems

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .