シーケンス生成マクロ

シーケンス生成マクロ

シーケンスの一般項を入力してシーケンスを広範囲に書き込むマクロを探しています。

私が言いたいのは、\GenSeq{general term}{index}{min index}{max index}例えば

\GenSeq{f(i)}{i}{1}{n} 生産する

ここに画像の説明を入力してください

\GenSeq{f(i)}{i}{k}{n} 生産する

ここに画像の説明を入力してください

\GenSeq{\theta^{(s)}}{s}{s}{T}

ここに画像の説明を入力してください

こんなものがLaTeXでプログラムできるのだろうか

答え1

ここに画像の説明を入力してください

\documentclass{article}

\def\GenSeq#1#2#3{%
\def\zz##1{#1}%
\def\zzstart{#2}%
\zz{#2},
\ifx\zzstart\zzzero\zz{1}\else\ifx\zzstart\zzone\zz{2}\else\zz{#2+1}\fi\fi,
\ldots,\zz{#3}}
\def\zzzero{0}
\def\zzone{1}
\begin{document}

\parskip\bigskipamount

$\GenSeq{f(#1)}{1}{n}$

$\GenSeq{f(#1)}{k}{n}$

$\GenSeq{\theta^{(#1)}}{s}{T}$

\end{document}

答え2

を使用した実装expl3

最初の必須引数は\GenSeqテンプレートであり、#1「ループ」内の現在のインデックスを表します。2 番目の引数は開始点、3 番目の引数は終了点です。

2番目の引数が整数(正規表現、0個または1個のハイフン/マイナス記号、1つ以上の数字で認識)の場合、2番目に印刷される項目には計算されたインデックスが含まれます<start point>+1。それ以外の場合は、

  1. 開始点と終了点が一致する場合は、1 つの項目だけが印刷されます。
  2. 開始点が数値で、終了点も数値で 1 または 2 異なる場合は、関連する項目のみが印刷されます。
  3. それ以外の場合は、開始項目、次のドット、終了項目が印刷されます。

を使用すると\GenSeq*、無限シーケンスであることを示すために末尾にドットが追加されます。

\documentclass{article}
\usepackage{amsmath}
%\usepackage{xparse} % not needed with LaTeX 2020-10-01 or later

\ExplSyntaxOn

\NewDocumentCommand{\GenSeq}{smmm}
 {% #1 = optional *
  % #2 = template
  % #3 = starting point
  % #4 = end point
  \pinkcollins_genseq:nnn { #2 } { #3 } { #4 }
  \IfBooleanT{#1}{,\dotsc}
 }

\cs_new_protected:Nn \pinkcollins_genseq:nnn
 {
  % turn the template into a (temporary) function
  \cs_set:Nn \__pinkcollins_genseq_temp:n { #1 }
  % do the main work
  \tl_if_eq:nnTF { #2 } { #3 } 
   {% if #2=#3, not much to do
    \__pinkcollins_genseq_temp:n { #2 }
   }
   {% now the hard work
    \__pinkcollins_genseq_do:nn { #2 } { #3 }
   }
 }

\cs_new_protected:Nn \__pinkcollins_genseq_do:nn
 {% #1 = start point, #2 = end point
  % first check whether #1 is an integer
  % \-? = one optional minus sign
  % [[:digit:]]+ = one or more digits
  % \Z = up to the end of the input
  \regex_match:nnTF { \-? [[:digit:]]+ \Z } { #1 }
   {
    \__pinkcollins_genseq_number:nn { #1 } { #2 }
   }
   {
    \__pinkcollins_genseq_symbolic:nn { #1 } { #2 }
   }
 }

\cs_new_protected:Nn \__pinkcollins_genseq_number:nn
 {% #1 = start point, #2 = end point
  \tl_if_eq:enTF { \int_eval:n { #1 + 1 } } { #2 }
   {
    \__pinkcollins_genseq_temp:n { #1 },\__pinkcollins_genseq_temp:n { #2 }
   }
   {
    \__pinkcollins_genseq_temp:n { #1 },
    \__pinkcollins_genseq_temp:n { \int_eval:n { #1+1 } },
    \tl_if_eq:enF { \int_eval:n { #1 + 2 } } { #2 } { \dots, }
    \__pinkcollins_genseq_temp:n { #2 }
   }
 }
\prg_generate_conditional_variant:Nnn \tl_if_eq:nn { e } { T, F, TF }

\cs_new_protected:Nn \__pinkcollins_genseq_symbolic:nn
 {% #1 = start point, #2 = end point
  \__pinkcollins_genseq_temp:n { #1 },
  \__pinkcollins_genseq_temp:n { #1+1 },
  \dots,
  \__pinkcollins_genseq_temp:n { #2 }
 }

\ExplSyntaxOff

\begin{document}

$\GenSeq{f(#1)}{1}{n}$

$\GenSeq{f(#1)}{0}{n}$

$\GenSeq{f(#1)}{1}{1}$

$\GenSeq{f(#1)}{1}{2}$

$\GenSeq{f(#1)}{1}{3}$

$\GenSeq{f(#1)}{1}{4}$

$\GenSeq{f(#1)}{-2}{k}$

$\GenSeq{f(#1)}{k}{n}$

$\GenSeq*{\theta^{(#1)}}{s}{T}$

\end{document}

ここに画像の説明を入力してください


-variantの別の使い方としては、*シーケンスを降順で作成することが挙げられます。

\documentclass{article}
\usepackage{amsmath}
%\usepackage{xparse} % not needed with LaTeX 2020-10-01 or later

\ExplSyntaxOn

\NewDocumentCommand{\GenSeq}{smmm}
 {% #1 = optional * for reverse sequence
  % #2 = template
  % #3 = starting point
  % #4 = end point
  \IfBooleanTF{#1}
   {
    \cs_set:Nn \__pinkcollins_genseq_sign: { - }
   }
   {
    \cs_set:Nn \__pinkcollins_genseq_sign: { + }
   }
  \pinkcollins_genseq:nnn { #2 } { #3 } { #4 }
 }

\cs_new_protected:Nn \pinkcollins_genseq:nnn
 {
  % turn the template into a (temporary) function
  \cs_set:Nn \__pinkcollins_genseq_temp:n { #1 }
  % do the main work
  \tl_if_eq:nnTF { #2 } { #3 } 
   {% if #2=#3, not much to do
    \__pinkcollins_genseq_temp:n { #2 }
   }
   {% now the hard work
    \__pinkcollins_genseq_do:nn { #2 } { #3 }
   }
 }

\cs_new_protected:Nn \__pinkcollins_genseq_do:nn
 {% #1 = start point, #2 = end point
  % first check whether #1 is an integer
  % \-? = one optional minus sign
  % [[:digit:]]+ = one or more digits
  % \Z = up to the end of the input
  \regex_match:nnTF { \-? [[:digit:]]+ \Z } { #1 }
   {
    \__pinkcollins_genseq_number:nn { #1 } { #2 }
   }
   {
    \__pinkcollins_genseq_symbolic:nn { #1 } { #2 }
   }
 }

\cs_new_protected:Nn \__pinkcollins_genseq_number:nn
 {% #1 = start point, #2 = end point
  \tl_if_eq:enTF { \int_eval:n { #1 \__pinkcollins_genseq_sign: 1 } } { #2 }
   {
    \__pinkcollins_genseq_temp:n { #1 },\__pinkcollins_genseq_temp:n { #2 }
   }
   {
    \__pinkcollins_genseq_temp:n { #1 },
    \__pinkcollins_genseq_temp:n { \int_eval:n { #1\__pinkcollins_genseq_sign: 1 } },
    \tl_if_eq:enF { \int_eval:n { #1 \__pinkcollins_genseq_sign: 2 } } { #2 } { \dots, }
    \__pinkcollins_genseq_temp:n { #2 }
   }
 }
\prg_generate_conditional_variant:Nnn \tl_if_eq:nn { e } { T, F, TF }

\cs_new_protected:Nn \__pinkcollins_genseq_symbolic:nn
 {% #1 = start point, #2 = end point
  \__pinkcollins_genseq_temp:n { #1 },
  \__pinkcollins_genseq_temp:n { #1\__pinkcollins_genseq_sign:1 },
  \dots,
  \__pinkcollins_genseq_temp:n { #2 }
 }

\ExplSyntaxOff

\begin{document}

\textbf{Ascending}

$\GenSeq{f(#1)}{1}{n}$

$\GenSeq{f(#1)}{0}{n}$

$\GenSeq{f(#1)}{1}{1}$

$\GenSeq{f(#1)}{1}{2}$

$\GenSeq{f(#1)}{1}{3}$

$\GenSeq{f(#1)}{1}{4}$

$\GenSeq{f(#1)}{-2}{k}$

$\GenSeq{f(#1)}{k}{n}$

$\GenSeq{\theta^{(#1)}}{s}{T}$

\textbf{Descending}

$\GenSeq*{f(#1)}{n}{1}$

$\GenSeq*{f(#1)}{n}{0}$

$\GenSeq*{f(#1)}{1}{1}$

$\GenSeq*{f(#1)}{2}{1}$

$\GenSeq*{f(#1)}{3}{1}$

$\GenSeq*{f(#1)}{4}{1}$

$\GenSeq*{f(#1)}{k}{-2}$

$\GenSeq*{f(#1)}{k}{n}$

$\GenSeq*{\theta^{(#1)}}{s}{T}$

\end{document}

ここに画像の説明を入力してください

答え3

expl3 で遊んで楽しむために、expl3 を使ってやってみたいと思いました。

しかし、最終的には expl3 と独自のコードを組み合わせて実行しました。

  • 私はexpl3-regex-codeを使ってチェックしています⟨最小インデックス⟩— (!) トークンを展開せずに⟨最小インデックス⟩⁠ ⁠(!)⁠—最大1つの符号といくつかの10進数のシーケンスを形成し、そうであれば、(増加した)値を増分して置換ルーチンに渡す。⟨最小インデックス⟩
  • 置き換えには独自のコードを使用します⟨索引⟩内で⟨総称⟩

⟨最小インデックス⟩有効なTeXのみを表すか生成するかをチェックするために展開されません。⟨番号⟩-量私は、このようなチェック/テストの考えを以下の理由で拒否します。完全に拡張されているかどうかを確認するためのテスト方法がない。⟨最小インデックス⟩有効なTeXのみを生成します。⟨番号⟩- 何らかの欠陥がなく、ユーザー入力の可能性に制限を課さない量がわかっている。このようなテストのアルゴリズムを実装しようとすると、停止問題に直面することになります。それらを展開するときに、トークンを形成する⟨最小インデックス⟩任意の拡張ベースのアルゴリズムを形成する可能性がある。そのようなアルゴリズムが最終的に有効なTeXを生成するかどうかをチェックするアルゴリズムを持つ。⟨番号⟩-量とは、他の任意のアルゴリズムがまったく終了するかどうか、またはエラー メッセージなしで終了するかどうかをアルゴリズムがチェックすることを意味します。これが停止問題です。アラン・チューリングは1936年に証明した任意のアルゴリズムに対して、そのアルゴリズムが終了するかどうかを「決定」できるアルゴリズムを実装することは不可能である。

当初は、⟨索引⟩expl3ルーチンによっても:

パート VII - l3tl パッケージ - トークン リスト、 セクション3 トークンリスト変数の変更インターフェース3.pdf(2020-10-27 リリース) には次のように記載されています:

\tl_replace_all:Nnn ⟨tl var⟩ {⟨old tokens⟩} {⟨new tokens⟩}

置き換えすべての出現⟨古いトークン⟩の中に⟨tl 変数⟩⟨新しいトークン⟩⟨古いトークン⟩{}または(より正確には、カテゴリコード1(グループ開始)または2(グループ終了)の明示的な文字トークン、およびカテゴリコード6のトークン)を含むことはできません#。この関数は左から右に作用するため、パターン⟨古いトークン⟩交換後も残る場合があります (\tl_remove_all:Nn例については を参照してください)。

(カテゴリ コード 1 は「begin-group」、カテゴリ コード 2 は「end-group」であると説明されています。カテゴリ コード 6 は「parameter」であると説明されていないのはなぜでしょうか。 ;-) )

でやってみました\tl_replace_all:Nnn

しかし、この発言は真実ではないため失敗しました。

(自分でテストすることができます:

以下の例では、 のすべての出現uが に置き換えられるわけではありませんd

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\tl_set:Nn \l_tmpa_tl {uu{uu}uu{uu}}
\tl_replace_all:Nnn \l_tmpa_tl {u} {d}
\tl_show:N \l_tmpa_tl
\stop

⟨古いトークン⟩u
⟨新しいトークン⟩ですd
すべての制限⟨古いトークン⟩そして⟨新しいトークン⟩従われます。

コンソール出力は次のとおりです。

\l_tmpa_tl=dd{uu}dd{uu}.

カテゴリ コード 1 (開始グループ) と 2 (終了グループ) を持つ、一致する明示的な文字トークンのペア間でネストされていない出現のみが置換されるようです。

したがって、すべての出現が置き換えられるという記述は誤りです。

ステートメントが正しければ、コンソール出力は次のようになります。

\l_tmpa_tl=dd{dd}dd{dd}.

そこで、expl3 を使わずに、独自の置換ルーチンを\ReplaceAllIndexOcurrences最初から作成することにしました。

副作用として、\ReplaceAllIndexOcurrencesカテゴリ コード 1 のすべての明示的な文字トークンが に置き換えられ、カテゴリ コード 2 のすべての明示的な文字トークンが に置き換えられます。{1}2

\documentclass[landscape, a4paper]{article}

%===================[adjust margins/layout for the example]====================
\csname @ifundefined\endcsname{pagewidth}{}{\pagewidth=\paperwidth}%
\csname @ifundefined\endcsname{pdfpagewidth}{}{\pdfpagewidth=\paperwidth}%
\csname @ifundefined\endcsname{pageheight}{}{\pageheight=\paperheight}%
\csname @ifundefined\endcsname{pdfpageheight}{}{\pdfpageheight=\paperheight}%
\textwidth=\paperwidth
\oddsidemargin=1.5cm
\marginparsep=.2\oddsidemargin
\marginparwidth=\oddsidemargin
\advance\marginparwidth-2\marginparsep
\advance\textwidth-2\oddsidemargin
\advance\oddsidemargin-1in
\evensidemargin=\oddsidemargin
\textheight=\paperheight
\topmargin=1.5cm
\footskip=.5\topmargin
{\normalfont\global\advance\footskip.5\ht\strutbox}%
\advance\textheight-2\topmargin
\advance\topmargin-1in
\headheight=0ex
\headsep=0ex
\pagestyle{plain}
\parindent=0ex
\parskip=0ex 
\topsep=0ex
\partopsep=0ex
%==================[eof margin-adjustments]====================================

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand\GenSeq{mmmm}{
  \group_begin:
  % #1 = general term
  % #2 = index
  % #3 = min index
  % #4 = max index
  \regex_match:nnTF { ^[\+\-]?\d+$ }{ #3 }{
    \int_step_inline:nnnn {#3}{1}{#3+1}{\ReplaceAllIndexOcurrences{#1}{#2}{##1},}
  }{
   \ReplaceAllIndexOcurrences{#1}{#2}{#3},
   \ReplaceAllIndexOcurrences{#1}{#2}{#3+1},
  }
  \ldots,
  \ReplaceAllIndexOcurrences{#1}{#2}{#4}
  \group_end:
}
\ExplSyntaxOff

\makeatletter
%%//////////////////// Code of my own replacement-routine: ////////////////////
%%=============================================================================
%% Paraphernalia:
%%    \UD@firstoftwo, \UD@secondoftwo,
%%    \UD@PassFirstToSecond, \UD@Exchange, \UD@removespace
%%    \UD@CheckWhetherNull, \UD@CheckWhetherBrace,
%%    \UD@CheckWhetherLeadingTokens, \UD@ExtractFirstArg
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@removespace{}\UD@firstoftwo{\def\UD@removespace}{} {}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral\expandafter\UD@secondoftwo\string{\expandafter
  \UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
  \UD@secondoftwo\string}\expandafter\z@\UD@secondoftwo}%
  {\expandafter\z@\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's first token is a catcode-1-character
%%.............................................................................
%% \UD@CheckWhetherBrace{<Argument which is to be checked>}%
%%                      {<Tokens to be delivered in case that argument
%%                        which is to be checked has leading
%%                        catcode-1-token>}%
%%                      {<Tokens to be delivered in case that argument
%%                        which is to be checked has no leading
%%                        catcode-1-token>}%
\newcommand\UD@CheckWhetherBrace[1]{%
  \romannumeral\expandafter\UD@secondoftwo\expandafter{\expandafter{%
  \string#1.}\expandafter\UD@firstoftwo\expandafter{\expandafter
  \UD@secondoftwo\string}\expandafter\z@\UD@firstoftwo}%
  {\expandafter\z@\UD@secondoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's leading tokens form a specific 
%% token-sequence that does neither contain explicit character tokens of 
%% category code 1 or 2 nor contain tokens of category code 6:
%%.............................................................................
%% \UD@CheckWhetherLeadingTokens{<argument which is to be checked>}%
%%                              {<a <token sequence> without explicit 
%%                                character tokens of category code
%%                                1 or 2 and without tokens of
%%                                category code 6>}%
%%                              {<internal token-check-macro>}%
%%                              {<tokens to be delivered in case
%%                                <argument which is to be checked> has
%%                                <token sequence> as leading tokens>}%
%%                              {<tokens to be delivered in case 
%%                                <argument which is to be checked>
%%                                does not have <token sequence> as
%%                                leading tokens>}%
\newcommand\UD@CheckWhetherLeadingTokens[3]{%
  \romannumeral\UD@CheckWhetherNull{#1}{\expandafter\z@\UD@secondoftwo}{%
    \expandafter\UD@secondoftwo\string{\expandafter
    \UD@@CheckWhetherLeadingTokens#3{\relax}#1#2}{}}%
}%
\newcommand\UD@@CheckWhetherLeadingTokens[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
  {\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
  {\expandafter\expandafter\expandafter\expandafter
   \expandafter\expandafter\expandafter\z@\expandafter\expandafter
   \expandafter}\expandafter\UD@secondoftwo\expandafter{\string}%
}%
%%-----------------------------------------------------------------------------
%% \UD@internaltokencheckdefiner{<internal token-check-macro>}%
%%                              {<token sequence>}%
%% Defines <internal token-check-macro> to snap everything 
%% until reaching <token sequence>-sequence and spit that out
%% nested in braces.
%%-----------------------------------------------------------------------------
\newcommand\UD@internaltokencheckdefiner[2]{%
  \@ifdefinable#1{\long\def#1##1#2{{##1}}}%
}%
\UD@internaltokencheckdefiner{\UD@InternalExplicitSpaceCheckMacro}{ }%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%
%%   \romannumeral\UD@ExtractFirstArgLoop{ABCDE\UD@SelDOm} yields  {A}
%%
%%   \romannumeral\UD@ExtractFirstArgLoop{{AB}CDE\UD@SelDOm} yields  {AB}
%%.............................................................................
\@ifdefinable\UD@RemoveTillUD@SelDOm{%
  \long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
  {\z@#1}%
  {\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%
%%=============================================================================
%% \ReplaceAllIndexOcurrences{<term with <index>>}
%%                           {<index>}%
%%                           {<replacement for<index>>}%
%%
%% Replaces all <index> in <term with <index>> by <replacement for<index>>
%%
%% !!! Does also replace all pairs of matching explicit character tokens of
%%     catcode 1/2 by matching braces!!!
%% !!! <index> must not contain explicit character tokens of catcode 1 or 2 !!!
%% !!! <index> must not contain tokens of catcode 6 !!!
%% !!! Defines temporary macro \UD@temp, therefore not expandable !!!
%%-----------------------------------------------------------------------------
\newcommand\ReplaceAllIndexOcurrences[2]{%
  % #1 - <term with <index>>
  % #2 - <index>
  \begingroup
  \UD@internaltokencheckdefiner{\UD@temp}{#2}%
  \expandafter\endgroup
  \romannumeral\UD@ReplaceAllIndexOcurrencesLoop{#1}{}{#2}%
}%
\newcommand\UD@ReplaceAllIndexOcurrencesLoop[4]{%
  % Do:
  %  \UD@internaltokencheckdefiner{\UD@temp}{<index>}%
  %  \romannumeral\UD@ReplaceAllIndexOcurrencesLoop
  %                                 {<term with <index>>}%
  %                                 {<sequence created so far, initially empty>}%
  %                                 {<index>}%
  %                                 {<replacement for<index>>}%
  %
  % #1 - <term with <index>>
  % #2 - <sequence created so far, initially empty>
  % #3 - <index>
  % #4 - <replacement for<index>>
  \UD@CheckWhetherNull{#1}{\z@#2}{%
    \UD@CheckWhetherLeadingTokens{#1}{#3}{\UD@temp}{%
      \expandafter\expandafter\expandafter\UD@ReplaceAllIndexOcurrencesLoop
      \expandafter\expandafter\expandafter{%
        \expandafter\UD@firstoftwo\expandafter{\expandafter}\UD@temp#1%
      }{#2#4}%
    }{%
      \UD@CheckWhetherLeadingTokens{#1}{ }{\UD@InternalExplicitSpaceCheckMacro}{%
         \expandafter\UD@ReplaceAllIndexOcurrencesLoop
         \expandafter{\UD@removespace#1}{#2 }%
      }{%
        \UD@CheckWhetherBrace{#1}{%
          \expandafter\expandafter\expandafter\UD@PassFirstToSecond
          \expandafter\expandafter\expandafter{%
          \expandafter\UD@PassFirstToSecond\expandafter{%
            \romannumeral\expandafter\UD@ReplaceAllIndexOcurrencesLoop
              \romannumeral\UD@ExtractFirstArgLoop{#1\UD@SelDOm}{}{#3}{#4}%
          }{#2}}%
          {\expandafter\UD@ReplaceAllIndexOcurrencesLoop\expandafter{\UD@firstoftwo{}#1}}%
        }{%
          \expandafter\UD@PassFirstToSecond\expandafter{%
            \romannumeral\expandafter\UD@Exchange\romannumeral\UD@ExtractFirstArgLoop{#1\UD@SelDOm}{\z@#2}%
          }{\expandafter\UD@ReplaceAllIndexOcurrencesLoop\expandafter{\UD@firstoftwo{}#1}}%
        }%
      }%
    }%
    {#3}{#4}%
  }%
}%
\makeatother
%%=============================================================================
%%///////////////// End of code of my own replacement-routine. ////////////////

\makeatletter
\newcommand\ParenthesesIfMoreThanOneUndelimitedArgument[1]{%
  \begingroup
  \protected@edef\UD@temp{#1}%
  \expandafter\expandafter\expandafter\UD@CheckWhetherNull
  \expandafter\expandafter\expandafter{\expandafter\UD@firstoftwo\UD@temp{}.}{%
    \endgroup#1%
  }{%
    \expandafter\UD@CheckWhetherNull
    \expandafter{\romannumeral\expandafter\expandafter
                              \expandafter            \expandafter
                              \expandafter\expandafter
                              \expandafter            \z@
                              \expandafter\expandafter
                              \expandafter            \UD@firstoftwo
                              \expandafter\UD@firstoftwo
                              \expandafter{%
                              \expandafter}%
                              \UD@temp{}.}{%
      \endgroup#1%
    }{%
      \endgroup(#1)%
    }%
  }%
}%
\makeatother

\begin{document}

Let's use \verb|i| as \textit{$\langle$index$\rangle$}---\verb|$\GenSeq{f(i)}{i}{1}{n}$| yields:

$\GenSeq{f(i)}{i}{1}{n}$

\vfill

Let's use \verb|i| as \textit{$\langle$index$\rangle$}, but \textit{$\langle$min~index$\rangle$} not a digit  sequence---\verb|$\GenSeq{f(i)}{i}{k}{n}$| yields:

$\GenSeq{f(i)}{i}{k}{n}$

\vfill

Let's use \verb|s| as \textit{$\langle$index$\rangle$}---\verb|$\GenSeq{\theta^{(s)}}{s}{s}{T}$| yields:

$\GenSeq{\theta^{(s)}}{s}{s}{T}$

\vfill

Let's use \verb|\Weird\Woozles| as \textit{$\langle$index$\rangle$}---\begin{verbatim}
$\GenSeq{%
          \sqrt{%
            \vphantom{(}%
            ParenthesesIfMoreThanOneUndelimitedArgument{\Weird\Woozles}\cdot\ParenthesesIfMoreThanOneUndelimitedArgument{\Weird\Woozles}%
            \vphantom{)}%
          }%
        }%
        {\Weird\Woozles}%
        {s}%
        {T}$
\end{verbatim} yields:

$\GenSeq{%
          \sqrt{%
            \vphantom{(}%
            \ParenthesesIfMoreThanOneUndelimitedArgument{\Weird\Woozles}\cdot\ParenthesesIfMoreThanOneUndelimitedArgument{\Weird\Woozles}%
            \vphantom{)}%
          }%
        }%
        {\Weird\Woozles}%
        {s}%
        {T}$

\vfill

Let's use the explicit space token as \textit{$\langle$index$\rangle$}---\verb|$\GenSeq{f( )}{ }{k}{n}$| yields:

$\GenSeq{f( )}{ }{k}{n}$

\vfill

Let's use the explicit space token as \textit{$\langle$index$\rangle$}---\verb|$\GenSeq{f( )}{ }{-5}{n}$| yields:

$\GenSeq{f( )}{ }{-5}{n}$

\vfill\vfill

\end{document}

ここに画像の説明を入力してください

関連情報