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.

4
  • The example on page 7 of the thrmtools manual also loads thm-restate. Sep 8, 2023 at 20:40
  • @JohnKormylo thm-restate is automatically loaded by thmtools
    – mbert
    Sep 8, 2023 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. Sep 8, 2023 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 9, 2023 at 20:44

3 Answers 3

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}
3
  • 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 8, 2023 at 20:54
  • The manual did mention that some counters are automatically reset (page 17). It could also be a local vs. global issue. Sep 8, 2023 at 20:57
  • By default only equation is reset, so this should not affect my issue
    – mbert
    Sep 8, 2023 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}
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

You must log in to answer this question.

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