4

I'm in a computer science formal languages / computability / complexity course, and I have to type a lot of sequences... Sometimes I have to edit the terms, add terms, remove terms, etc., and doing it by hand seems messy.

Is it possible to generate a sequence of terms (not necessarily numbers) with subscripts automatically, given perhaps the term label and length of sequence for starters, and then possible additional options like: step, which terms to include, commas/spaces, etc.?

Basically, I want something like this:

enter image description here enter image description here

From perhaps something like this:

\seq{a}{1..2n}{1,3,2}
Skip(L)=\{~\seq{a}{1..2n-1}{2,2,1} ~|~ \seq{a}{1..2n}{1,3,2} \text{ is in } L~\}

Instead of having to write this:

a_1~a_2~a_3~\ldots~a_{2n-1}~a_{2n}
Skip(L)=\{~a_1~a_3~\ldots~a_{2n-1} ~|~ a_1~a_2~a_3~\ldots~a_{2n-1}~a_{2n} \text{ is in } L~\}

Maybe there is a discrete math or formal languages package specifically that can do this? I'm Googling, but haven't found what I'm looking for yet.

  • 1
    What does each argument do? I mean \seq{a}{1...2n} seems logical for me, what do the other arguments do? – Manuel Feb 1 at 23:32
  • @Manuel Those extra arguments might be for specifying number of specified starting terms and number of ending terms, e.g. {2,1} And the other argument was for a maybe a step, e.g. every term {1}, or every other term {2}, etc. Don't know if anything like that exists though... – delrocco Feb 1 at 23:41
  • @delrocco Can we assume you will always only input 1 item, three dots, and last item? Or you want more flexibility? – Manuel Feb 1 at 23:44
  • @Manuel The number of terms at start and end of sequence are not critical I'd say to most sequences, and a good start if you have a solution for that. I'm using my professor specific sequences here in his notes/homeworks. Also, I could see sequences when they would be critical. – delrocco Feb 1 at 23:44
5

Syntax: \seq[⟨steps before ellipsis⟩,⟨steps after ellipsis⟩]{⟨term label⟩}[⟨step⟩]{⟨first index⟩,...,⟨last index⟩} where every [..] is optional.

\documentclass{scrartcl}

\usepackage{mathtools,amssymb}
\DeclareMathOperator\Skip{Skip}

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand \seq { o m o m }
 {
  \group_begin:
  \IfValueT {#1}
   {
    \int_set:Nn \l_delrocco_ini_int { \clist_item:nn {#1} {1} }
    \int_set:Nn \l_delrocco_fin_int { \clist_item:nn {#1} {2} }
   }
  \IfValueT {#3}
   {
    \int_set:Nn \l_delrocco_step_int { #3 }
   }
  \delrocco_seq:nn { #2 } { #4 }
  \group_end:
 }

\int_new:N  \l_delrocco_ini_int
\int_set:Nn \l_delrocco_ini_int  { 3 }
\int_new:N  \l_delrocco_fin_int
\int_set:Nn \l_delrocco_fin_int  { 2 }
\int_new:N  \l_delrocco_step_int
\int_set:Nn \l_delrocco_step_int { 1 }


\cs_set_eq:NN \math_sb:n \sb

\cs_new_protected:Npn \delrocco_seq:nn #1 #2
 {
  \int_step_inline:nnnn
   { \clist_item:nn {#2} {1} }
   { \l_delrocco_step_int }
   { \clist_item:nn {#2} {1} + (\l_delrocco_ini_int - 1) * \l_delrocco_step_int }
   { #1 \math_sb:n { ##1 } \, }
  \!\cdots  
  \int_step_inline:nnnn
   { (\l_delrocco_fin_int - 1) * \l_delrocco_step_int }
   { -\l_delrocco_step_int }
   { \l_delrocco_step_int }
   { #1 \math_sb:n { \clist_item:nn {#2} {3} - ##1 } \, }
  #1 \math_sb:n { \clist_item:nn {#2} {3} }
 }
\ExplSyntaxOff

\begin{document}
$\seq[4,4]{a}[2]{5,...,2n}$
\[
  \Skip(L) = \{ \seq[2,1]{a}{1,...,2n-1} \mid \seq{a}{1,...,2n} \in L \}
\]
\end{document}

If you don't want the spaces remove every instance of \, and \!.

  • This is nice! I'm customizing it a bit. I take it there is no standard package for doing formal language stuff like this? – delrocco Feb 2 at 0:37
  • I modified it so all the optionals are in one array, and the default start and end number of terms is 1. So you use it like \seq[3,3,2]{a}{1,...,2n} or \seq{a}{3,...,2n-3}. Thank you very much for your response! – delrocco Feb 2 at 1:05
  • The thing with my solution was that you could change separately the step or the other without needing to input everything. But ok! – Manuel Feb 2 at 8:28
  • Yea I noticed that. Your solution is more general. I figured most of the time I would be supplying the start and end terms only if modifying the step, so I just threw it all into one optional argument - but that may turn out to be incorrect lol We'll see ~ – delrocco Feb 3 at 4:45
2

With some pain in programming it, the following macros seem to do what you like with a not very complicated syntax.

\seq{<variable>}{<start>..<end>}[<initial>,<final>,<step>]

where <final> and <step> can be omitted and are both set to 1 in this case. If the optional argument is missing, [2,1,1] is implied.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\seq}
 {
  m                               % base letter
  >{\SplitArgument{1}{..}}m       % <start>..<stop>
  >{\SplitArgument{2}{,}}O{2,1,1} % <initial>,<final>,<step>
 }
 {
  \delrocco_seq_print:nnnnnn { #1 } #2 #3
 }

\cs_new_protected:Nn \delrocco_seq_print:nnnnnn
 {
  \tl_if_novalue:nTF { #5 }
   {
    \__delrocco_seq_print:nnnnnn { #1 } { #2 } { #3 } { #4 } { 1 } { 1 }
   }
   {
    \tl_if_novalue:nTF { #6 }
     {
      \__delrocco_seq_print:nnnnnn { #1 } { #2 } { #3 } { #4 } { #5 } { 1 }
     }
     {
      \__delrocco_seq_print:nnnnnn { #1 } { #2 } { #3 } { #4 } { #5 } { #6 }
     }
   }
 }

\cs_new_protected:Nn \__delrocco_seq_print:nnnnnn
 {
  \mathopen{}
  \int_step_inline:nnnn { #2 } { #6 } { #2+(#4-1)*#6 }
   { \mathbin{}\nobreak #1\sb{##1} }
  \mathbin{}\nobreak\dots
  \__delrocco_seq_break:n { #3 }
  \int_step_inline:nnnn { 0-(#5-1)*#6 } { #6 } { 0 }
   {
    \mathbin{}\nobreak
    #1\sb
     {
      \l__delrocco_seq_base_tl
      \int_compare:nTF { \l__delrocco_seq_index_int + (##1) < 0 }
       {
        \int_to_arabic:n { \l__delrocco_seq_index_int + (##1) }
       }
       {
        \int_compare:nF { \l__delrocco_seq_index_int + (##1) = 0 }
         {
          \tl_if_empty:NF \l__delrocco_seq_base_tl { + }
          \int_to_arabic:n { \l__delrocco_seq_index_int + (##1) }
         }
       }
     }
   }
   \mathclose{}
 }

\seq_new:N \l__delrocco_seq_temp_seq
\tl_new:N \l__delrocco_seq_temp_tl
\tl_new:N \l__delrocco_seq_base_tl
\int_new:N \l__delrocco_seq_index_int

\cs_new_protected:Nn \__delrocco_seq_break:n
 {
  \regex_split:nnN { ([\+\-]?[0-9]+\Z) } { #1 } \l__delrocco_seq_temp_seq
  % the last item is empty if there is a base and an index
  \seq_pop_right:NN \l__delrocco_seq_temp_seq \l__delrocco_seq_temp_tl
  \seq_if_empty:NTF \l__delrocco_seq_temp_seq
   {
    \tl_set:Nn \l__delrocco_seq_base_tl {#1}
    \int_set:Nn \l__delrocco_seq_index_int { 0 }
   }
   {
    % the last but one item is the number
    \seq_pop_right:NN \l__delrocco_seq_temp_seq \l__delrocco_seq_temp_tl
    % the base
    \tl_set:Nx \l__delrocco_seq_base_tl { \seq_use:Nn \l__delrocco_seq_temp_seq {} }
    % the index
    \int_set:Nn \l__delrocco_seq_index_int { \l__delrocco_seq_temp_tl }
   }
 }


\ExplSyntaxOff

\begin{document}

$|\seq{a}{1..20}|$

$|\seq{a}{1..2n}[2,2,1]|$

$|\seq{a}{1..2n-1}[3,2,2]|$

$|\seq{a}{1..2n+1}[3,2,2]|$

$|\seq{a}{1..13}[3,2,2]|$

$\operatorname{Skip}(L)=
 \{ \seq{a}{1..2n-1}[2,1,2] \mid \seq{a}{1..2n}[3,2]\text{ is in } L \}
$

$\operatorname{Skip}(L)=
 \{ \seq{a}{1..2n-1}[2,2,2] \mid \seq{a}{1..2n}[3,3]\text{ is in } L \}
$

\end{document}

I didn't allow symbolic calculations for the starting point, but it could be added. No consistency check is done, as it would require quite a lot of algebra.

The space between items is twice \medmuskip, because an empty binary operation is set between any two items. Thisenter image description here can be customized.

  • Thank you! I modified @Manuel version so that it is used very similar to this. But this solution is technically 3 characters shorter to use, and some optional, optional arguments, which is cool. I wish I was as good as you guys as meta-programming :) – delrocco Feb 3 at 4:37

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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