如何定义冯诺依曼自然数(newcommand,带有for循环)?

如何定义冯诺依曼自然数(newcommand,带有for循环)?

我如何定义一个新命令,\natset[1]{#1}使其给出如下输出?

使用/输出示例

(∅ = \varnothing);预期用途是数学模式例如$\natset[1]{#1}$。牙套是人们通常会用到的东西$\{ \}$


生活在 TeX-ic 伪代码领域,我可能会这样做:

\newcommand{\natset}[1]{%
    iter_set := \varnothing
    \foreach \n in {1,...,#1}{%
        temp_set := iter_set∪{iter_set}
        iter_set := temp_set
    \return iter_set}
  • 我怎样才能将这样的循环转换成 LaTeX (以便进行编译pdflatex)?

我尝试过各种组合、、\newcommand\renewcommand/\noexpand\expandafter业务,但没有任何合理的结果。

基本前言和测试用例:

\documentclass[12pt]{article}

\usepackage{amsmath} %for \text inside $$ $$
\usepackage{amssymb} %for \varnothing
%\usepackage{xifthen} %maybe needed
\usepackage{tikz} %for-loop

%definition here
\makeatletter
\newcommand{\natset}[1]{#1}
\makeatother


\begin{document}

    $$\text{0 gives}\qquad \natset{0}$$
    $$\text{1 gives}\qquad \natset{1}$$
    $$\text{2 gives}\qquad \natset{2}$$
    $$\text{8 gives}\qquad \natset{8}$$
    
\end{document}

我以后还有关于这个命令的其他计划(比如添加可选参数、将样式更改为 Zermelo 的自然数等)。冯·诺依曼的东西希望能让我入门。当然,任何复杂的答案都是受欢迎的,但更简单的答案(从句法上来说)可能最有帮助。或者带有一些额外评论的复杂答案。

答案1

我认为使用递归比循环更自然,例如

在此处输入图片描述

\documentclass{article}
\usepackage{amssymb}


\newcommand\nnatset[1]{%
 \ifnum#1=0 \varnothing \else
 \ifnum#1>1 \nnatset{\numexpr#1-1},\{\fi\nnatset{\numexpr#1-1}\ifnum#1>1 \}\fi
 \fi}
\newcommand\natset[1]{\ifnum#1>0\{\fi\nnatset{#1} \ifnum#1>0\}\fi}

\begin{document}

$\natset{0}$

$\natset{1}$

$\natset{2}$

$\natset{3}$

\end{document}

答案2

这个解决方案的有趣之处在于,我实际上将其构建为空组的 TeX 组(即根据放置在宏中的实际冯·诺依曼分组\z)。然后我使用tokcycle以可排版的方式解释 catcode-1,2 组。

\documentclass{article}
\usepackage{tokcycle,amssymb}
\newcommand{\natset}[1]{\def\z{}\natsetaux{#1}}
\newcommand\natsetaux[1]{%
  \ifnum\numexpr#1\relax>0\relax
    \edef\z{\z{\z}}%
    \natsetaux{#1-1}%
  \else
    \expandedtokcyclexpress{{\z}}%
  \fi}
\Groupdirective{%
  \if\relax#1\relax\varnothing\else
  \ifnum\tcdepth>1\relax,\fi\{\processtoks{#1}\}\fi}
\begin{document}

$\natset 0$

$\natset 1$

$\natset 2$

$\natset 3$

$\natset 4$
\end{document}

在此处输入图片描述

为了更好地理解,对于\natset 3, 的值是d 模式\z中的 catcode 1 和 2 个括号(不可排版)\detokenize

在此处输入图片描述

然后,每次在输入流中遇到括号组时,tokcycle都会将扩展的输入输入到其中{\z}并执行。在里面,术语指的是组的内容。如果它是一个空组,我会排版。否则,我会根据需要放置一个逗号,并将非空组内容重新提交给标记循环,同时将排版括号放在结果周围。生成的排版给出\Groupdirective\Groupdirective#1\varnothing

在此处输入图片描述

最后,我只想补充一点,上面的实现\natsetaux是为了便于理解而编写的。但是,它在递归过程中使用了堆栈,因为\fis 会不断积累,并且只有在最终完成时才会释放。对于 的小参数来说,这不是问题\natset。但是,如果要将其用于大量扩展,最好以\natsetaux一种在下一次递归调用之前完成自身的方式重新实现。以下是这样的一种方法:

\newcommand\natsetaux[1]{\tctestifnum{#1>0}{\edef\z{\z{\z}}%
     \expandafter\natsetaux\expandafter{\the\numexpr#1-1}}
    {\expandedtokcyclexpress{{\z}}}}

答案3

粗制 LaTeX3 溶液:

\documentclass{article}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\int_new:N \l_natset_tmpa_int

\NewDocumentCommand \natset { m }
  {
    \int_set:Nn \l_natset_tmpa_int { #1 }

    \int_compare:nNnTF { \l_natset_tmpa_int } = { 0 }
      {
        \varnothing
      }
      {
        \{ \varnothing
        \int_step_inline:nnn { 1 } { \l_natset_tmpa_int - 1 }
          {
            , \natset { ##1 }
          }
        \}
      }
  }

\ExplSyntaxOff

\begin{document}

\begin{align*}
0 &= \natset{0} \\
1 &= \natset{1} \\
2 &= \natset{2} \\
3 &= \natset{3} \\
4 &= \natset{4} \\
5 &= \natset{5}
\end{align*}

\end{document}

在此处输入图片描述

相关内容