1

Thinking about this question, I'd like to use thmtools' restatable environment to store theorems with a number in the csname. That way one can loop through them at the end of the document to restate each one. My issue is that the way thmtools stores this csname seems to prevent expansion of commands within.

Here's an example that works. \somecmd steps through a counter and stores its argument in cmd-1, cmd-2, etc.

\documentclass{article}

\newcounter{foo}

\newcommand{\somecmd}[1]{% \stepcounter{foo}% \expandafter\def\csname cmd-\thefoo\endcsname{#1}% }

\begin{document} \somecmd{A} \somecmd{B} \somecmd{C}

\UseName{cmd-1} \UseName{cmd-2} \UseName{cmd-3}

\ExpandArgs{c}\ShowCommand{cmd-1} \ExpandArgs{c}\ShowCommand{cmd-2} \end{document}

The output is A B C and the log shows

> \cmd-1=macro:
->A.
<argument> \cmd-1

l.19 \ExpandArgs{c}\ShowCommand{cmd-1}

> \cmd-2=macro: ->B. <argument> \cmd-2

l.20 \ExpandArgs{c}\ShowCommand{cmd-2}

as expected.

Now here's a try with restatable where \declaretheoremx works like \declaretheorem but also defines an environment saved<thmname> that stores its contents in a command thm-<num>. Since the environment grabs its contents we need to use the +b argspec.

\documentclass{article}
\usepackage{kantlipsum,amsthm,thmtools}

\newcounter{savedthmcount}

\newcommand{\declaretheoremx}[2][]{ \declaretheorem[#1]{#2} \NewDocumentEnvironment{saved#2}{+b}{% \stepcounter{savedthmcount}% \begin{restatable}{#2}{thm-\thesavedthmcount} ##1 \end{restatable} }{} }

\declaretheoremx{theorem}

\begin{document}

\begin{savedtheorem} \kant[2][1] \end{savedtheorem}

\begin{savedtheorem} \kant[3][1] \end{savedtheorem}

\UseName{thm-1}* \UseName{thm-2}*

\ExpandArgs{c}\ShowCommand{thm-1} \ExpandArgs{c}\ShowCommand{thm-2} \end{document}

thms

Everything works as expected except that each command thm-<num> is just the last theorem called. In the log we get

> \thm-1=macro:
->\@ifstar {\thmt@thisistheonefalse \csname thmt@stored@thm-\thesavedthmcount \
endcsname }{\thmt@thisistheonetrue \csname thmt@stored@thm-\thesavedthmcount \e
ndcsname }.
<argument> \thm-1

l.31 \ExpandArgs{c}\ShowCommand{thm-1}

> \thm-2=macro: ->@ifstar {\thmt@thisistheonefalse \csname thmt@stored@thm-\thesavedthmcount
endcsname }{\thmt@thisistheonetrue \csname thmt@stored@thm-\thesavedthmcount \e ndcsname }. <argument> \thm-2

l.32 \ExpandArgs{c}\ShowCommand{thm-2}

which makes it seem like the stored csname is the literal string thmt@stored@thm-\thesavedthmcount instead of thmt@stored@thm-thm-1, thmt@stored@thm-thm-2, etc.

What is going wrong here? The definition of the restatable environment in thm-restate.sty is somewhat complicated but I don't see anything that would "protect" the argument from expansion.

Edit: This seems to work but I'd still like to know specifically what's going wrong without this trick.

mbert
  • 4,171
  • The example on page 7 of the thrmtools manual also loads thm-restate. – John Kormylo Sep 08 '23 at 20:40
  • @JohnKormylo thm-restate is automatically loaded by thmtools – mbert Sep 08 '23 at 20:48
  • your thm-1 macro is obviously not fully expanded, it contains commands like \@ifstar and \thesavedthmcount and what this commands do will depend on their meaning when you use the command. \ExpandArgs{nnx}\begin{restatable}{#2}{thm-\thesavedthmcount} should work. – Ulrike Fischer Sep 08 '23 at 22:40
  • @UlrikeFischer Thanks. Sorry to ask a follow-up in the comments but if I wanted to allow the optional argument for restatable like \begin{restatable}[##1]{#2}{thm-\thesavedthmcount}, what would be the argument of \ExpandArgs? For example \ExpandArgs{nxnx} doesn't seem to work – mbert Sep 09 '23 at 20:44

3 Answers3

0

I tried to reproduce your problem, but this code runs fine.

\documentclass{article}
\usepackage{thmtools, thm-restate}
\declaretheorem{theorem}

\newcounter{foo} %\renewcommand{\thefoo}{\alph{foo}}

\begin{document}

\stepcounter{foo} \begin{restatable}[Euclid]{theorem}{test\thefoo} \label{thm:euclid}% For every prime $p$, there is a prime $p’>p$. In particular, the list of primes, \begin{equation}\label{eq:1} 2,3,5,7,\dots \end{equation} is infinite. \end{restatable}

\stepcounter{foo} \begin{restatable}[Euclid]{theorem}{test\thefoo} \label{thm:euclid}% Every integer greater than 1 has a unique prime decomposition. \end{restatable}

\setcounter{foo}{0} \loop\ifnum\value{foo}<2 \stepcounter{foo}% \csname test\thefoo\endcsname* \repeat

\end{document}

John Kormylo
  • 79,712
  • 3
  • 50
  • 120
  • Thank you, however I don't think this answers my question of what's wrong with packaging this in a new environment. The goal is not to do the counter stepping and naming manually – mbert Sep 08 '23 at 20:54
  • The manual did mention that some counters are automatically reset (page 17). It could also be a local vs. global issue. – John Kormylo Sep 08 '23 at 20:57
  • By default only equation is reset, so this should not affect my issue – mbert Sep 08 '23 at 20:59
0

Just use the \edef trick mentioned in this answer.

\documentclass{article}
\usepackage{kantlipsum,amsthm,thmtools}

\newcounter{savedthmcount}

\newcommand{\declaretheoremx}[2][]{ \declaretheorem[#1]{#2} \NewDocumentEnvironment{saved#2}{O{}+b}{% \stepcounter{savedthmcount}% \edef\temp{% \noexpand\begin{restatable}[##1]{#2}{thm-\thesavedthmcount}% }% \temp ##2 \end{restatable} }{} }

\declaretheoremx{theorem}

\begin{document}

\begin{savedtheorem} \kant[1][1] \end{savedtheorem}

\begin{savedtheorem} \kant[3][1] \end{savedtheorem}

\UseName{thm-1}* \UseName{thm-2}*

\end{document}

mbert
  • 4,171
0

restatable doesn't perform expansion in its second argument (the label) and you want to expand it. The recent \ExpandArgs facility is your friend.

I made a few changes to the definition of \declaretheoremx:

  1. \NewDocumentCommand is more powerful;
  2. the counter is allocated as part of it;
  3. a trailing optional argument is added (default is the same as the main argument) for the prefix.
\documentclass{article}
\usepackage{kantlipsum,amsthm,thmtools}

\NewDocumentCommand{\declaretheoremx}{O{}mO{#2}}{% \newcounter{saved#2}% \declaretheorem[#1]{#2}% \NewDocumentEnvironment{saved#2}{+b}{% \stepcounter{saved#2}% \ExpandArgs{nne}\begin{restatable}{#2}{#3-\UseName{thesaved#2}} ##1 \end{restatable}% }{}% }

\declaretheoremx{theorem}[thm]

\begin{document}

\section{Main text}

First a theorem

\begin{savedtheorem} \kant[2][1] \end{savedtheorem}

Another theorem

\begin{savedtheorem} \kant[3][1] \end{savedtheorem}

\section{The statements}

\UseName{thm-1}* \UseName{thm-2}*

\end{document}

enter image description here

egreg
  • 1,121,712