打开/关闭菜单
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

序数记号编写指南

来自Googology Wiki

本条目相对系统性地介绍序数记号的定义方法,同时为新人创作自己的记号提供一定的指引。本文来自Asheep233的知乎文章。

记号的分类及组成成分

按输出类型给记号分类

按输出类型分类,Googology 社区中的绝大部分记号可被分为两类:

大数记号 给定表达式,输出一个自然数的记号

序数记号 给定表达式,输出一个序数的记号

在Googology 社区内,所谓的序数记号往往不直接给出序数,而是给定一个表达式,能输出它的基本列。因此如下的概念界定也是必要的:

序数函数 一个 \(f:\rm Ord→Ord\) 的函数,直接输出一个序数。如\( \rm Ordinal\ Collapsing\ Function\) 。

序关系序数记号 有一个合法表达式集以及一个全序关系。

基本列序数记号 有一个合法表达式集,并且给定一个合法表达式,能给出它的基本列。

本条目讨论的对象是基本列序数记号。下面的所有序数记号均指代基本列序数记号。

按定义/良序程度给序数记号分类

按定义/良序程度分类,Googology 社区中的大部分序数记号可被分为如下三类:

严格良序的记号 它是良定义 (Well-defined) 的,且被证明是良序 (Well-ordered) 的。

形式化良定义的记号 它使用形式化语言定义(如编程语言),且是良定义的,但未必是良序的。

非形式化良定义的记号 它使用非形式化语言定义(往往是自然语言),且是良定义的,但未必是良序的。

非良定义的记号 它是非良定义的。

本条目的目的是给出一种记号的的非形式化良定义方案,并讨论几种常见的非良定义的情况。

序数记号的组成成分及良序/良定义性

一个基本列序数记号一般包含如下成分:

1.合法表达式集 这是所有合法表达式组成的集合。绝大多数情况下,我们通过合法性判定给出这样的集合。

2.基本列映射 这是一个算法,给定一个合法的表达式,能够输出它的基本列。这个操作又称为展开。

3.极限/后继判定 能判定哪些序数是极限序数,哪些序数是后继序数。

4.偏序关系 可由上述概念直接得到。如果表达式 β 在 α 的基本列中,那么 β< α 。

除此之外,在基本列序数记号中往往还有下列概念/性质(但不一定是必须的):

5.极限表达式及其基本列 极限表达式一般记作Limit 。其基本列又称作极限基本列。

6.标准表达式集 这是所有从极限表达式开始取基本列,能得到的表达式的集合。它是合法表达式集的子集。

7.完备性 能表达极限表达式下方的所有序数。

如果一个序数记号的同时具备上述前三点,且它们能被它的定义唯一确定,那么这个序数记号就是(广义)良定义的。如果它不同时具备上述前三点,那么就是定义不全的(特别地,如果标准表达式集不是合法表达式集的子集,那么也是定义不全的);如果它具备上述前三点,但它们无法被定义唯一确定,那么就是定义不明的。缺少定义和定义不明统称为(广义)非良定义。

如果第四点中的偏序关系是一个良序关系,那么这个序数记号就是良序的。

狭义的良定义性蕴含良序性。狭义的非良定义就是定义不明。

良定义记号的定义方案

下面我们介绍一种良定义记号的定义方案。

记号良定义的基本要求

良定义性为记号的定义提出了最基本的要求。

一方面,它要求记号同时拥有完整的合法表达式集、基本列映射以及极限/后继判定,即定义完整。这意味着「以此类推式」的定义是不可接受的。例如,下面的定义方式就是一个经典的非良定义方式:

\(0,1=0,0,0,…\\ 0,1,1=0,1,0,1,0,1,…\\ 0,1,2=0,1,1,1,…\\ 0,1,2,3=0,1,2,2,2,…\\ \rm Limit=0,1,2,3,4,…\\ \)

按社区的一些默认,我们假定上面的四个展开式都是唯一确定的(按 PrSS 式展开),并默认它拥有和 PrSS 一样的后继规则。尽管如此,这个记号依然是非良定义的,因为它的定义不全。

它没有给出合法表达式的判定方法。

它缺少部分表达式的展开方式(如 0,1,2,2 的基本列是未定义的)。

这是「以此类推式」定义的核心缺陷:它只给出了少数几个表达式的展开方式,而其余的所有表达式都依赖读者的个人脑补。它代表典型的定义不全。

另一方面,它要求记号的合法表达式集、基本列映射以及极限/后继判定是可以被规则唯一确定的,即无歧义。这意味着记号定义中涉及到的所有概念和算法必须清晰。下例是一个经典的定义不明的定义:

极限表达式: (0,(1,(2,(⋯,(n,0)))))

(#,n+1)=(#,n)(#,n)⋯(#,n)

(n+1,#1)找 (n,#2)展开

(#)(0)=(#)+1

其中的第三条:「(n+1,#1)找(n,#2)展开」即定义不明之处。在这里它并没有解释「找…展开」是什么操作,导致了歧义。

记号的定义写法

一个记号想要是良定义的,必须是定义完整且定义明确的。除此之外,如果它要能参与社区交流并获得理解和认可,它的定义最好是易读、令人舒适的。

对于非形式化语言定义的记号,由于这种语言的模糊性,是否良定义更多是一种主观性质。这种情况下,记号的定义越详尽,越能让人确信它足够良定义。

本条目建议,可按如下流程去书写一个记号的定义:

Step 1 明确记号的形式

第一步是让读者明确此记号采用的表达式形式。例如:

BMS的每一个表达式是一个矩阵。

Y序列的每一个表达式是一个正整数序列。

PSS Hydra的每一个表达式是一个由 (0,+,p_n()) 组成的字符串。

这一步看似微不足道,但仍然必须足够明确,否则也可能导致歧义。例如,如果你像上文一样只说

BMS的每一个表达式是一个矩阵。

但在后文用到了 \((a_1,a_2,a_3\cdots,a_n)(b_1,b_2,b_3,\cdots,b_n)\) 这样的形式,却不说明一个小括号是一行还是一列,就会导致严重的歧义。

一个经典的故事是,有人曾经试图教会AI 如何展开 BMS ,但在教学的时候忘了说小括号指代的是列不是行,最终导致AI 展开出了完全混乱的表达式。

因此,对形式的描述也需要在适当程度内尽可能详细:

BMS 的每一个表达式是一个矩阵,写作 \((a_1,b_1,c_1,\cdots)(a_2,b_2,c_2,\cdots)\cdots\) ,其中每一个括号是矩阵的一列, \(a_1,a_2,a_3,…,a_n\) 等是矩阵的一行。矩阵由 0 开头,每列自上而下单调不增。

PSS Hydra的每一个表达式是一个由 \((0,+,p_n())\)组成的字符串。 \(p_n() \)之间可以互相包含,形如\(p_1(p_2(0))\) ; \(p_n()\) 只能直接包含 \(p_{k}(),k≤n+1\) ;只有 \(p_1()\)可以不被任何 \(p_n()\) 包含;\(p_n(0)\) 记作 \(p_n\) 。

也可以通过几个体现记号形式的典型性质的例子,使读者尽快理解此记号的形式:

诸如 (0,0,0)(1,1,1) , (0,0,0)(1,1,1)(2,1,0)(1,1,1) 的表达式都是BMS 的合法表达式。

诸如 \(p_1+p_1 , p_1(p_2) , p_1(p_2(p_1)+p_2) \)的表达式都是PSS Hydra 的合法表达式。

总之,你需要保证记号的形式是唯一确定且无歧义的。这不仅保证了良定义,也利于定义接下来的规则。

Step 2 定义合法表达式

一个序数记号需要能判定一个表达式是否合法。

但对于许多序数记号来说,这样的一个合法性判定和展开规则一样令人头疼。因此,社区往往有这样一个默认:

凡是能够通过定义中的展开方式进行展开的表达式为合法表达式

这实际上是把定义「合法表达式」这样一个大且困难的任务,分散到了展开规则的每一个语句中。严格地来说,这种说法是不严谨的,因为可能存在一些合法但坏的表达式。这种情况会在Step 4介绍。

尽管如此,给出合法性的一些必要不充分条件(如果不满足则一定不合法的条件),可以显著地增加记号定义的易读性。简单的条件可以被写在Step 1中的「记号的形式」中。如果你给出的条件是某些有一定复杂度的算法,可以在定义中单列出来。例如:

一个标准的 BMS 应当满足如下的条件:

(1) 首列的所有元素都应当为零。

(2) 同列中排在下面的项不大于排在上面的项。

(3) 每一个非零项都至多为其父项 +1 。

Step 3 定义记号中的概念

一个记号的定义往往会用到许多全新的概念,或者需要调用已有的概念。这些都需要预先声称。除了自然语言中已有的词汇和概念(除非你给它们赋予了新的含义),其余的概念都必须定义明确。

在上文中我们提到了这样的一个定义语句:「(n+1,#1) 找 (n,#2) 展开」,它就定义了一种新的概念「 A 找 B 展开」,这就是一个全新的概念。也许作者脑中知道这个概念是什么意思,但如果没有在定义中解释,那么阅读定义的人就无法理解这个概念。

Step 3.1 找到概念的逻辑层次

层次化你的概念会使得一切更加清晰。定义记号类似于做一道菜:你需要先准备食材,进行一级、二级的预处理,最终完成下锅、出盘。在这个过程中,预处理一个食材也许会用到另一种食材,你也需要准备锅碗瓢盆等多种工具,这就形成了逻辑关系的层级。例如, BMS的概念间有这样的关系图:

BMS的概念关系图

此图中,对象均用紫色表示。粉色表示记号形式,绿色表示展开规则。

在定义「展开规则」之前,有诸多的前置概念需要按逻辑顺序一步步定义。例如,定义坏根需要先定义祖先项和父项,而每一行都有不同的父项关系和找父项规则,因此需要先定义行标。

如果定义概念 A 需要先定义概念 B ,但你先定义了 A ,这就会造成读者阅读的困惑。概念的循环定义更会造称记号定义逻辑的崩溃。这也是为什么我们需要先定义记号的形式:因为记号的形式往往是在逻辑上最基础的概念之一,例如在上图中,矩阵形式决定了行标。

有些时候记号概念的逻辑层级会相当复杂。这时为了保持定义的整体感,有可能会需要出现上面的「先定义 A 」的情况,这时候你可以给出一个索引,说明定义 A 需要用到后文的什么概念(或者在后文的哪里会给出一个具体的定义)。

Step 3.2 给每个概念赋予定义

你需要从自然语言出发,明确每一个概念的含义。如果你调用了已有的概念(例如其他记号的定义),需要附加说明。

记号概念往往分为两类:规则类和对象类。

对于对象类概念,它可以是表达式的一部分,也可以不是。无论如何,你都需要明确它所指代的含义,并往往要给出一个判定(计算)方法(读者能判断一个对象是否属于这个概念),即定义概念的外延。

对于规则类概念,如果是定义其它概念所需要的,可以按逻辑层次,布设在定义前段部分恰当的位置(例如 ω-\rm Y 山脉图的画法);如果已经是最终展开规则的一部分,就定义在「展开规则」的部分。规则类的具体定义要求会在Step 4中介绍。

例如,一种常见的写法如下:

父元:从一个元素a出发,先沿右腿向上一格,再沿左腿向左下一步,就到达a的父元。

祖先:“父元”关系的传递闭包。此处祖先不含自身。

后代:如果a是b的祖先,那么b是a的后代。

右上角:最右列中最上端的元素。

根元素与具体的记号有关。

根元素所在的列是根列,但根列元素并非其字面含义。

根列元素指的是根元素及其下方所有元素。注意:不含根元素上方的元素!

……

复制部分是根列以右(不含)、最右列以左(含)的部分。其宽度称为复制宽度。

……

减一操作在Y系列记号中就是简单的把原序列最右元素减去1,但在mountain notation系列记号则稍显复杂,而且与具体的记号有关。

上面的定义对于「父元」、「祖先」、…、「magma元素」等对象类概念,都给出了明确的判定方法。

而对于「根元素与具体的记号有关」等定义,给出了一个索引,保持了文章定义的整体感。

此外,社区中如下的一些概念已经具有了一定的内涵,可以直接调用它们的名称:

( BMS 形式矩阵的)表观行、列;行标、列标;提取、左腿、右腿;LNZ ;坏根;坏部、好部;简单拼接;阶差向量;(Hydra形式的)包含、根节点、叶节点、父节点、子节点、层级。

适当的调用可以使你的定义更易读。但请注意,你仍然需要定义这些概念的具体的判定方法。你能调用的只有名称以及它们的内涵。

Step 4 定义展开规则

在Step 3中我们完成了展开规则所需要前置概念的定义。接下来,我们需要完成最终展开规则的定义。

定义展开规则,就是定义一个算法,对于任何一个合法表达式 X ,都能算出 \(X[n]\)。

一般有两种常见的定义思路。

第一种方法是直接写出其计算方法,即 \(X[n]=(…)\) 。例如:

\[ψ(k+1)[n]=\underbrace{ψ(k)+ψ(k)+…+ψ(k)}_{n次}\\ \]

第二种方法是从已有的表达式开始展开,即得到 \(X_1X_2X_3…X_n\) (其中\( X_n \)是某个表达式的一部分),然后取展开了 n (或者 n+1 等)次的表达式作为 X[n] 。例如:

对于 G+B+L ,展开为\( G+B+B_1+B_2+……+B_n\) ,其中 + 是简单拼接。截取到 \(B_n\) 作为第 n 项基本列。

第二种方法的自由度一般更高(它先指定了展开式再确定基本列),是一般Worm/Hydra 式记号的定义思路。尤其是当记号的山脉图结构较为复杂时,第二种方法更符合人的展开直觉。但同时,它有歧义的风险也更高。

接下来,你需要有逻辑地书写展开规则的定义,即一步步定义记号的展开顺序。同时,可以善用「如果,否则」和「跳转到xx步」或者「重复xx步的操作」,来使展开更有秩序。而对于前文提到的,不属于最终展开规则的规则类定义,也可以用这样的方法定义。

下面的 ω-Y 展开规则就是一个正面范例:

(1) 将末列的各项减一。如果最上方的元素被减为零,则删去它相关的左腿和右腿。

(2) 从最上方的根列元素开始,找到其作用区域。

(3) 在这一根列元素作用区域内找到所有的轮廓边,并将轮廓边的端点及其所指的元素向右上方进行复制。

具体地,向右平移(末列位置 − 根列位置)的列数,然后向上平移至满足以下条件的位置:若平移前端点所指的元素与根列元素行差为\(δ_0\) ,那么平移后对应端点所指的元素与末列最上方的元素行差也要为 \(δ_0 \)。像这样,直至所有的轮廊边和它们所指的元素都被复制到了新的位置上。

(4) 如果末列最上方元素与根列元素的行差为 0,则在这一根列元素作用区域内找到所有的填充边,然后将它不断复制,并填补到轮廓边提升所产生的所有缝隙之中。特别地,当填充边被复制到跨过了 n阶分隔线的位置上时,其左腿和右腿的行差需要为 \(ω^{n-1}\) 。

(5) 在这一根列元素作用区域内找到所有的非轮廓边,并对这些边进行复制。非轮廓边左腿指向的元素都保持不动,而右腿向右或右上平移,向右平移的列数为(末列位置 − 根列位置)。如果这条非轮廓边右腿所指元素没有被这个作用区域内的轮廊边所指到,那么无需向上平移;如果有,那么向上平移到与末列最上方元素行差为 \(δ_0\) 的位置,其中\( δ_0\) 为平移之前该元素与根列元素的行差。

(6) 自上而下不断地对各个根列元素所对应的山脉图重复 (3) − (5) 的操作,直到山脉图的所有部分都完成复制。

(7) 按照从上到下、从左到右的顺序将山脉图中的各个元素计算出来。如果该元素不是山脉图某一部分的顶端元素,则其取值等于该元素正上方的元素与其父项之和。

在这个定义中,作者同时采用了顺序结构(按步执行)、分支结构(如果否则)和循环结构(重复…的操作),这种类似于代码的展开规则书写方式,不仅尽可能地排除了歧义,而且令人赏心悦目。

请保证你的展开规则覆盖了可能出现的所有情况。否则那些没有被覆盖到的表达式,要么按照上文提到的默认被判定为非法表达式,导致定义缺失;要么与已有的合法表达式定义相悖,导致定义不良。

想象一条流水线:从极限表达式(上游)开始,源源不断地流来各式各样的标准表达式。不同的表达式会得到对应工序的处理,得到展开式。理想的情况下,每一个表达式都应能得到它的展开式。一旦你的流水线缺乏了某道工序,使得一些表达式无法展开,这就导致了定义不全。

有一些作者会为上述流程留下一个「出口」,使得标准但无法被规则判定展开的表达式从此流出,成为坏的表达式,往往以后继形式展开。这往往意味着记号的定义暂时仍有缺陷,需要修复。

有时定义记号中的一些概念会涉及非标准展开(即展开非标准式),这种情况下,上面的定义流程也要考虑到这些非标准式。

Step 5 优化定义

这一步是整个记号定义的收尾工作。

在这里,你可以从头到尾审视一遍已有的记号定义,修改其中的纰漏,并完善排版、定义结构,润色语言。

你可以加入一些解释性文字和表达式形式/展开示例,这可以帮助读者更快速地理解你的记号。解释性文字可以放在开头、中间或结尾,可以解释记号的思路、发展历程或者每一步具体操作的原因。例如[5]:

Y系列记号,其表达式是个正整数序列,每个元素都压缩了许多信息,不能立即辨认,需要画出山脉图(whYmountain)才可以看到其结构。山脉图分为行、列,列标与行标的二元组可以定位山脉图中的一个元素。列标是正整数,每一列对应原来序列的一个元素;行标则是序数:理想中α-Y山脉图的行标是小于\(\omega^{1+\alpha}\)的序数。

mountain notation系列记号则显式地表达山脉图,而无需像Y系列记号那样需要解压、压缩。mountain notation系列记号的表达式是矩阵[n],此n也就是展开时的FS项数。

在这个记号的前言中,作者解释了记号和Y系列记号的关系,帮助读者快速找到这个记号「山脉图记号」的定位。

除此之外,你可以附上记号的枚举和已有的分析。它们是帮助读者了解你的记号的最快方式。它们不一定要十分详细,但一定要体现出记号的尽可能多的特性(形式上的或者展开上的),起到更好的引导作用。