我正在学习计算机科学形式语言/可计算性/复杂性课程,我必须输入很多序列...有时我必须编辑术语,添加术语,删除术语等,而手工完成这些似乎很混乱。
是否可以自动生成带有下标的术语序列(不一定是数字),也许首先给出术语标签和序列长度,然后可能给出附加选项,如:步骤、要包含哪些术语、逗号/空格等?
基本上,我想要这样的东西:
可能是这样的:
\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~\}
而不必这样写:
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~\}
也许有专门的discrete math
或formal languages
包可以做到这一点?我正在谷歌搜索,但还没有找到我要找的东西。
答案1
语法:\seq[⟨steps before ellipsis⟩,⟨steps after ellipsis⟩]{⟨term label⟩}[⟨step⟩]{⟨first index⟩,...,⟨last index⟩}
其中 every[..]
是可选的。
\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}
如果您不想要空格,请删除每个\,
和\!
。
答案2
尽管编程有些痛苦,但以下宏似乎可以用不太复杂的语法来做你喜欢的事情。
\seq{<variable>}{<start>..<end>}[<initial>,<final>,<step>]
其中<final>
和<step>
可以省略,在本例中均设置为 1。如果缺少可选参数,则[2,1,1]
隐含为。
\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}
我不允许对起点进行符号计算,但可以添加。没有进行一致性检查,因为这需要相当多的代数运算。