Creating a solution label for an exercise using \declaretheoremstyle

amsthmexercisesthmtoolsxsim

I am writing a book with exercises scattered throughout the text, for which solutions are presented at the end of each chapter.

I want the layout to be as follows:

An exercise environment is introduced inside the text. A solution to this exercise would later appear in the "Solution to exercises" section at the end of the chapter.

In addition, at the end of the exercise environment would be a page reference to the page where its solution is labeled.

A visual example (made artificially) is this:

enter image description here

And the last section of the chapter would be

enter image description here

Is it possible to do that using the amsthm and thmtools packages?

I would assume that the "Solution on page xx" string would be the value of the postfoothook key of the \declaretheoremstyle command of thmtools, but I don't know how to additionally insert a label into that value.

Maybe I am going too far, but I am also open for a way to do that using one of the exercise packages (xsim looks the most promising one). I just haven't stumbled upon this exact layout.


EDIT:

Since the final document is to be typeset in LyX, I think that a better way to achieve my goal is not to work with xsim, since for referencing, LyX works with the basic building stones of LaTeX – label, pageref and their friends.

I think that an appropriate code to be inserted into postfoothook and heading would do the job, but this is where I am asking for help:

The exercises and solutions labels would be in the following format:

  • ex:ch1:ratio-of-odd-numbers <-> sol:ex:ch1:ratio-of-odd-numbers
  • ex:ch2:rolling-n-sided-die <-> sol:ex:ch2:rolling-n-sided-die
  • ex:ch2:the-hotel-problem <-> sol:ex:ch2:the-hotel-problem

What I need is to refer to sol:⟨the exrecise label⟩ inside postfoothook in exercise, and to refer to ⟨the exrecise label⟩ in the heading of solution.

\begin{exercise}\label{ex:ch1:every-prime}
blah blah
\end{exercise}

for which a solution is in the format

\begin{solution}\label{sol:ex:ch1:every-prime}
Solution to blah blah.
\end{solution}
  1. To produce the ref "Solution on page xx" I need to concatenate sol: with ⟨the exrecise label⟩ to produce
\pageref{sol:⟨the exrecise label⟩}

where, in this example, ⟨the exrecise label⟩ is ex:every-prime (to create \pageref{sol:ex:ch1:every-prime}).

  1. To produce the header "Solution to Exercise xx" I need to remove the sol: part from the solution label to produce \ref{⟨the exrecise label⟩}, so in this example it would be, \ref{ex:ch1:every-prime}.

Any help about that?

A MWE:

\documentclass{book}
\usepackage{fontspec,hyperref,amsthm,thmtools}
%%
\declaretheoremstyle[
postfoothook = \rightline{Solution on page \pageref{sol:⟨the exrecise label⟩}
]{exercise}
\declaretheorem[style=exercise]{exercise}

\declaretheoremstyle[
heading = Solution to Exercise \ref{⟨the solution label without "sol:"⟩},
numbered=no,
]{solution}
\declaretheorem[style=solution]{solution}
%%
\begin{document}

\chapter{Prime numbers}
Lorem ipsum
\section{Dolor sit amet}
Consectetur adipiscing elit.

\begin{exercise}[Euclid]{ex:ch1:every-prime}
Prove that for every prime $p$, there is a prime $p^\prime > p$. In particular, the list of primes, $2, 3, 5, 7, \ldots$ , is infinite.
\end{exercise}

\section{Solution to exercises}
\begin{solution}\label{sol:ex:ch1:every-prime}
The proof is straight forward. First note that...
\end{solution}
\end{document}

Edit 2

As a follow up to muzimuzhi Z answer, I would like also to add an "Exercise with no solution" to my book. This environment may be named exercise-nosol and I want it to share the same counter with the exercise environment defined in the accepted answer.

How to do that?

That is, how to define the two environments (exercise with xsim, exercise-nosol with thmtool) so that they share the same counter?

I defined it using thmtools as follows:

\declaretheoremstyle[
postfoothook = \rightline{(No Solution) $\blacktriangleleft$}
]{exercise-nosol}
\declaretheorem[name=Exercise,numberwithin=chapter,style=exercise]{exercise}

output:
enter image description here

Best Answer

An xsim attempt, based on the "Example 5: Crossreferencing between problems and answers" shown in package manual.

\documentclass{article}
\usepackage{amssymb}
\usepackage{xsim,lipsum,hyperref}
\hypersetup{colorlinks}

\DeclareExerciseHeadingTemplate{custom}
  {\section{\XSIMexpandcode{\XSIMtranslate{default-heading}}}}

\DeclareExerciseEnvironmentTemplate{custom}
  {%
    \IfInsideSolutionTF
      {\label{sol:\ExerciseID}}
      {\label{ex:\ExerciseID}}%
    \paragraph*
      {%
        \XSIMmixedcase{\GetExerciseName}%
        \IfInsideSolutionTF
          {
            to \GetExerciseParameter{exercise-name}%
            ~\GetExerciseProperty{counter}%
            ~(From Page~\pageref{ex:\ExerciseID})
          }
          {%
            ~\GetExerciseProperty{counter}%
            \GetExercisePropertyT{subtitle}{~(\PropertyValue)}
          }%
      }%
  }
  {%
    \IfInsideSolutionF
      {\par\leavevmode\hfill
       Solution on page~\pageref{sol:\ExerciseID}~$\blacktriangleleft$}%
  }
\xsimsetup{
  exercise/template = custom ,
  solution/template = custom ,
  print-solutions/headings-template = custom
}

\begin{document}

\section{Exercises}
\begin{exercise}[subtitle=title]
  \lipsum[1][2]
\end{exercise}
\begin{solution}
  \lipsum[1][2]
\end{solution}

\begin{exercise}[subtitle=second title]
  \lipsum[4]
\end{exercise}
\begin{solution}
  \lipsum[4]
\end{solution}

\clearpage
\printsolutions

\end{document}

xsim output - exercise part

xsim output - solution part

Update: Support no-solution exercises

To avoid possible incompatibilities, here is an xsim-only attempt.

A new command \IfSolutionEmptyTF is provided which uses xsim internal \xsim_attribute_get:nn. This might not be the most robust way.

I've tried xsim's \IfExistSolutionTF and it seems to not work as I expected. Also probably due to an xsim issue (see cgnieder/xsim#90), currently you have to provide an empty solution environment for each of no-solution exercises, like

\begin{solution} % no empty lines in env contents
\end{solution}

Full example

\documentclass{article}
\usepackage{amssymb}
\usepackage{xsim,lipsum,hyperref}
\hypersetup{colorlinks}

\ExplSyntaxOn
\cs_generate_variant:Nn \tl_if_empty:nTF {e}

\NewExpandableDocumentCommand{\IfSolutionEmptyTF}{}
  {
    \tl_if_empty:eTF
      {
        \exp_args:Ne \xsim_attribute_get:nn
          {exercise!\ExerciseID} {solution-body}
      }
  }
\ExplSyntaxOff

\DeclareExerciseHeadingTemplate{custom}
  {\section{\XSIMexpandcode{\XSIMtranslate{default-heading}}}}

\DeclareExerciseEnvironmentTemplate{custom-exercise}
  {%
    \label{ex:\ExerciseID}%
    \paragraph*
      {%
        % typset "Exercise <num> (<subtitle>)"
        \XSIMmixedcase{\GetExerciseName}%
        ~\GetExerciseProperty{counter}%
        \GetExercisePropertyT{subtitle}{~(\PropertyValue)}
      }%
  }
  {%
      \par\leavevmode\hfill
      % typeset "Solution on page <page>" or "(No solution)"
      \ifcsname r@sol:\ExerciseID\endcsname
        Solution on page~\pageref{sol:\ExerciseID}%
      \else
        (No Solution)%
      \fi
      ~$\blacktriangleleft$%
  }

\DeclareExerciseEnvironmentTemplate{custom-solution}
  {%
    \IfSolutionEmptyTF{}
    {
      \label{sol:\ExerciseID}
      \paragraph*
        {%
          \XSIMmixedcase{\GetExerciseName}
          to \GetExerciseParameter{exercise-name}%
          ~\GetExerciseProperty{counter}%
          ~(From Page~\pageref{ex:\ExerciseID})
        }%
    }
  }{%
    \par
  }
\xsimsetup{
  exercise/template = custom-exercise ,
  solution/template = custom-solution ,
  print-solutions/headings-template = custom
}

\begin{document}

\section{Exercises}
\begin{exercise}[subtitle=title]
  \lipsum[1][2]
\end{exercise}
\begin{solution}
  \lipsum[1][2]
\end{solution}

\begin{exercise}[subtitle=no solution]
  \lipsum[3][1] aaa
\end{exercise}
% You still need to provide an empty solution environment.
\begin{solution}
\end{solution}

\begin{exercise}[subtitle=third title]
  \lipsum[4][1-3]
\end{exercise}
\begin{solution}
  \lipsum[4][4-6]
\end{solution}

\begin{exercise}[subtitle=fourth title]
  \lipsum[4][1-3]
\end{exercise}
\begin{solution}
  \lipsum[4][4-6]
\end{solution}

\clearpage
\printsolutions

\end{document}

xsim output 2 - exercise part xsim output 2 - solution part