6

I am trying to use the proof environment that comes with the amsthm package. And I would like the proof environment to be numbered, such as the theorem environment for the sake of adding a label, so I have added a custom counter in the preamble and changed the embedded \proofname in the proof environment. It all works well and displays my counters correctly in the text. However, when I try to reference my proofs, only the proof counter gets displayed instead of the full counter.

My code is below:

\documentclass[12pt,letterpaper]{article}

\usepackage{amsthm}
\usepackage{hyperref}

\newcounter{proof}[section] % adds a new counter for the proof environment included in the amsthm package that restarts for every new section
\renewcommand{\theproof}{\thesection.\arabic{proof}} % adds the section number before your proof counters
\renewcommand{\proofname}{\refstepcounter{proof}Proof \theproof} % the \proofname was embedded in your proof environment to output the italicized 'Proof', which is displayed at the beginning of every proof. This changes the \proofname to print 'Proof' and \theproof, which we defined as the section-proof counter above. This adds a counter to your proofs so you can hyperref them.

\newtheorem{definition}{Definition}[section]


\begin{document}
\section{One}
\begin{proof}
\label{p1}
this is proof one.
\end{proof}

This should reference proof \ref{p1}, which should display as proof 1.1.
\begin{definition}
\label{d1}
this is definition one.
\end{definition}
As we can see, this is not a problem when I reference definition \ref{d1}.

\section{Two}
\begin{proof}
\label{p2}
this is proof two.
\end{proof}
This should reference proof \ref{p2}, which should display as proof 2.1.

\begin{definition}
\label{d2}
this is definition two.
\end{definition}
As we can see, this is not a problem when I reference definition \ref{d2}.

\end{document}

But this is the result I get:

Enter image description here

4

You can manually set the label value by defining \@currentlabel at the start of the proof environment.

Adding something to the start of a command can be done using the xpatch package which provides the \xpretocmd (xpatch pre to command) macro. This works the same for environments, an environment like proof defines two commands, one that is executed with \begin{proof} which is internally called \proof, and one that is executed with \end{proof} which is internally called \endproof.

Patching the environment allows you to use the normal \label command instead of a newly defined labelling command.

Because \@currentlabel has an @ symbol in the name the redefinition should be enclosed in \makeatletter and \makeatother.

MWE:

\documentclass[12pt,letterpaper]{article}

\usepackage{amsthm}
\usepackage{xpatch}
\usepackage{hyperref}
\makeatletter
\xpretocmd{\proof}{\def\@currentlabel{\theproof}}{}{}
\makeatother

\newcounter{proof}[section] % adds a new counter for the proof environment included in the amsthm package that restarts for every new section
\renewcommand{\theproof}{\thesection.\arabic{proof}} % adds the section number before your proof counters
\renewcommand{\proofname}{\refstepcounter{proof}Proof \theproof} % the \proofname was embedded in your proof environment to output the italicized 'Proof', which is displayed at the beginning of every proof. This changes the \proofname to print 'Proof' and \theproof, which we defined as the section-proof counter above. This adds a counter to your proofs so you can hyperref them. 

\newtheorem{definition}{Definition}[section]

\begin{document}
\section{One}
\begin{proof}
\label{p1}
this is proof one.
\end{proof}

This should reference proof \ref{p1}, which should display as proof 1.1.
\begin{definition}
\label{d1}
this is definition one.
\end{definition}
As we can see, this is not a problem when I reference definition \ref{d1}.

\section{Two}
\begin{proof}
\label{p2}
this is proof two.
\end{proof}
This should reference proof \ref{p2}, which should display as proof 2.1.

\begin{definition}
\label{d2}
this is definition two.
\end{definition}
As we can see, this is not a problem when I reference definition \ref{d2}.

\end{document}

Result:

enter image description here

  • 1
    You could have just moved \refstepcounter to the beginning of \proof. BTW, \proofname is expanded inside inside a savebox, hence the local definition of \@currentlabel. Interestingly, the etoolbox \patchcmd didn't work on \proof. – John Kormylo Sep 8 at 15:59
  • @JohnKormylo \patchcmd doesn't work on commands that have an optional argument. The xpatch package was written for the purpose in order to avoid things such as \expandafter\patchcmd\csname\string\proof\endcsname for the particular case. – egreg Sep 8 at 21:26
2

Here is an approach that works, but I am not sure what is going on behind the scenes. I adapted the accepted answer from this question, though copying it verbatim increased the counter proof once when the environment began, and once when the label was defined, resulting in offset numbering, so I just decreased the counter every time the label is called.

After you define the counter proof, add the the following line:

\newcommand{\prooflabel}[1]{\addtocounter{proof}{-1}\refstepcounter{proof}\label{#1}}

Then whenever you have a proof, instead of \label, use \prooflabel as below.

\section{One}
\begin{proof}
\prooflabel{p1}
this is proof one.
\end{proof}

This should reference proof \ref{p1}, which should display as proof 1.1.

This is the result:

enter image description here

Perhaps someone more knowledgeable than me can adjust the \prooflabel and other definitions so that there isn't this back and forth couting, but it seems to work as you would like it to work.

2

Your \refstepcounter is issued inside the optional argument to \item and the corresponding value of \@currentlabel gets forgotten as soon as \item is processed, so you actually get references to the section number. You can check it by clicking on the reference.

A possible solution is to patch \proof (the command executed upon entering the proof environment) to issue \refstepcounter after \trivlist and before \item.

\documentclass[12pt,letterpaper]{article}

\usepackage{amsthm}
\usepackage{xpatch}
\usepackage{hyperref}

\newcounter{proof}[section]
\renewcommand{\theproof}{\thesection.\arabic{proof}}
\renewcommand{\proofname}{Proof \theproof}

\xpatchcmd{\proof}{\trivlist}{\trivlist\refstepcounter{proof}}{}{}

\newtheorem{definition}{Definition}[section]

\begin{document}
\section{One}
\begin{proof}
\label{p1}
this is proof one.
\end{proof}

This should reference proof \ref{p1}, which should display as proof 1.1.
\begin{definition}
\label{d1}
this is definition one.
\end{definition}
As we can see, this is not a problem when I reference definition \ref{d1}.

\section{Two}
\begin{proof}
\label{p2}
this is proof two.
\end{proof}
This should reference proof \ref{p2}, which should display as proof 2.1.

\begin{definition}
\label{d2}
this is definition two.
\end{definition}
As we can see, this is not a problem when I reference definition \ref{d2}.

\end{document}

enter image description here

You can also define a proof* environment for unnumbered proofs by saving a copy of \proof before patching it.

\documentclass[12pt,letterpaper]{article}

\usepackage{amsthm}
\usepackage{xpatch}
\usepackage{hyperref}

% save \proof
\let\unnumberedproof\proof
\newenvironment{proof*}
 {\renewcommand\proofname{Proof}\unnumberedproof}
 {\endproof}

\newcounter{proof}[section]
\renewcommand{\theproof}{\thesection.\arabic{proof}}
\renewcommand{\proofname}{Proof \theproof}

\xpatchcmd{\proof}{\trivlist}{\trivlist\refstepcounter{proof}}{}{}

\newtheorem{definition}{Definition}[section]

\begin{document}
\section{One}
\begin{proof}
\label{p1}
this is proof one.
\end{proof}

This should reference proof \ref{p1}, which should display as proof 1.1.
\begin{definition}
\label{d1}
this is definition one.
\end{definition}
As we can see, this is not a problem when I reference definition \ref{d1}.

\section{Two}
\begin{proof}
\label{p2}
this is proof two.
\end{proof}
This should reference proof \ref{p2}, which should display as proof 2.1.

\begin{definition}
\label{d2}
this is definition two.
\end{definition}
As we can see, this is not a problem when I reference definition \ref{d2}.

\begin{proof*}
An unnumbered proof.
\end{proof*}

\end{document}
  • Thank you for explaining why the \@currentlabel seemed to get wiped from my codes! This is a simple and efficient solution! – Carina Chen Sep 9 at 0:52
1

Looking at the code of the proof-environment reveals that \proofname is carried out only in case no optional argument is given. In this case \proofname gets carried out as part of the optional argument of a \trivlist's \item. Thus \proofname gets carried out within a local scope. \refstepcounter coming from carrying out \proofname will redefine \@currentlabel but that redefinition will also be restricted to that local scope.

I strongly recommend not to redefine \proofname as packages and LaTeX-infrastructure rely on it holding only the words used for introducing a proof.

I suggest redefining the proof-environment so that default for the optional argument will not be \proofname but another macro which in turn does both call the unmodified \proofname and call \refstepcounter and afterwards "globalize" \@currentlabel.

If you do it this way, passing an optional argument to the proof-environment will still not trigger the incrementing of the counter.

You can use \proofname as optional argument in order to get unnumbered proofs as usual.

\documentclass[12pt,letterpaper]{article}
\usepackage{xpatch}
\usepackage{amsthm}
\usepackage{hyperref}

\makeatletter
\newcounter{proof}[section]%
\renewcommand{\theproof}{\thesection.\arabic{proof}}%
\DeclareRobustCommand\prooflabel{%
  \refstepcounter{proof}%
  \global\let\@currentlabel\@currentlabel
  \lowercase\expandafter{%
    \expandafter\protected@xdef
    \expandafter\@currentlabelname\expandafter{\proofname\protect\nobreakspace\theproof}%
  }%
  \proofname~\theproof
}%
\xpatchcmd{\proof}{\itshape}{\itshape\gdef\@currentlabelname{#1}\csname phantomsection\endcsname}{}{}%
\expandafter\def\expandafter\proof\expandafter{%
  \expandafter\@protected@testopt\expandafter\proof\csname\string\proof\endcsname{\prooflabel}%
}%
\DeclareRobustCommand\LcUcfork[1]{#1}
\makeatother

\newtheorem{definition}{Definition}[section]

\begin{document}

\section{One}
\begin{proof}
\label{p1.1}
This is proof one.
\end{proof}

\begin{proof}[\LcUcfork{M}y special proof]%
\label{special}%
This is my special proof.
\end{proof}

\begin{proof}[\proofname]%
This proof is not numbered.
\end{proof}

\begin{proof}
\label{p1.2}
This is proof two.
\end{proof}

This should reference proof \ref{p1.1}, which should display as proof 1.1.

This should reference \nameref{p1.1}, which should display as proof 1.1.

This should reference {\let\LcUcfork=\lowercase\nameref{special}}, which should display as my special proof.


\begin{definition}
\label{d1.1}
This is definition one.
\end{definition}
As we can see, this is not a problem when I reference definition \ref{d1.1}.

\section{Two}
\begin{proof}
\label{p2.1}
This is proof two.
\end{proof}
This should reference proof \ref{p2.1}, which should display as proof 2.1.

This should reference \nameref{p2.1}, which should display as proof 2.1.

\begin{definition}
\label{d2.1}
This is definition two.
\end{definition}
As we can see, this is not a problem when I reference definition \ref{d2.1}.

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.