With this setup, you will state the theorems you want to be repeated in the introduction, without worrying about their number. The theorem body needs to be typed in just once.
Of course, you don't need to have all theorems in the introduction. If you have one that you don't need to restate, just type it in the document body normally.
\begin{futuretheorem}{<label>}[optional argument]
<theorem body>
\end{futuretheorem}
and in the document body you will use
\pasttheorem{<label>}
The body of the theorem is saved to be also typeset at the time when the theorem number will be known.
Full code:
\documentclass{article}
\usepackage{amsthm}
\usepackage{hyperref} % optional
\newtheorem{theorem}{Theorem}[section]
\newtheorem*{futuretheoreminner}{Theorem~\thefuturetheoreminner}
\newcommand{\thefuturetheoreminner}{} % initialize
\ExplSyntaxOn
\prop_new:N \g_alevel_future_prop
\NewDocumentEnvironment{futuretheorem}{ m o +b }
{% #1 is the label to be also used in the body for restating
% #2 is the standard optional argument for a theorem
% #3 is the body
\renewcommand{\thefuturetheoreminner}{\ref{#1}}
\IfNoValueTF{#2}
{\futuretheoreminner}
{\futuretheoreminner[#2]}
#3
}
{
\endfuturetheoreminner
\prop_gput:Nnn \g_alevel_future_prop { #1 } { #3 }
\IfValueT{#2}{ \prop_gput:Nnn \g_alevel_future_prop { #1-attr } { #2 } }
}
\NewDocumentCommand{\pasttheorem}{m}
{
\prop_if_in:NnTF \g_alevel_future_prop { #1-attr }
{
\begin{theorem}[\prop_item:Nn \g_alevel_future_prop { #1-attr }]
}
{
\begin{theorem}
}
\label{#1}
\prop_item:Nn \g_alevel_future_prop { #1 }
\end{theorem}
}
\ExplSyntaxOff
\begin{document}
\section{Introduction}
\begin{futuretheorem}{test1}
This is a theorem
\end{futuretheorem}
\begin{futuretheorem}{test2}[Important]
This is an important theorem
\end{futuretheorem}
\section{Test}
\pasttheorem{test1}
\section{Another}
\pasttheorem{test2}
\end{document}
With hyperref
the numbers in the introduction will be hyperlinks to the main part where the theorem is restated in context.

Doing the other way around, that is, typing in the theorem body only in the main part of the document, would require writing out it in an auxiliary file. But I believe that having all main theorems in a controlled place at the beginning is better.
What does the code do? First I define an auxiliary theorem-like environment naming it futuretheoreminner
. It is not numbered, because we'll supply the number automatically. Its label is Theorem~\thefuturetheoreminner
where the command with a long name a default definition of nothing: we'll redefine it later to contain the desired number.
Next we enter the expl3
programming layer and allocate a prop
variable (property list). This kind of variable contains items that we can think to have the form key=value
. How do we populate it?
The idea is that a call \begin{theorem}\label{foo}
defines a cross-reference for the theorem. So we'll use this system in order to retrieve the correct number, but in an indirect way.
A new environment futuretheorem
is defined that takes a mandatory argument (designed with m
, in the code #1
) and an optional argument (designed with o
, in the code #2
) and also the entire contents up to \end{futuretheorem}
(available in the code as #3
).
The job of this environment is to first see whether an optional argument (for the theorem note/attribution) is present. After this check the futureinnertheorem
environment is started, with the optional argument if present. But first \thefuturetheoreminner
command is redefined to contain \ref{#1}
, which will eventually produce the desired theorem number as it results from the main document body.
The contents of the environment is delivered and the environment is finished, but there's still something to do: store in the property list the environment's content with the key #1
and possibly the optional argument with the key #1-attr
.
The storing is global, because we're working inside an environment.
Now the \pasttheorem
command takes a mandatory argument, which is the key for the corresponding theorem stated in the introduction. If the optional argument is present, we call
\begin{theorem}[\prop_item:Nn \g_alevel_future_prop {#1-attr}]\label{#1}
so retrieving the optional argument added at the beginning, or just
\begin{theorem}\label{#1}
which will assign the desired label for the cross reference. Next we retrieve the body of the theorem we had stored and issue \end{theorem}
.
At the first run, \ref{test1}
will produce just ??, but that's normal. Once the run is finished, \label{test1}
will attach the correct number for the theorem in the introduction to be typeset.
thmtools
, §1.4, pp. 6-7. It defines arestatable
theorem environment.amsmath
cooperates withamsthm
, it is irrelevant here. I've therefore removed theamsmath
tag.