抽象代数是研究带有特定操作符(一个或多个)的集合的学科。在我们的讨论范围内,我们只关心其操作符为二元操作符的集合。

给定一个带有二元操作符的集合,我们可以根据二元操作符的行为以及集合中允许(或预期)存在的元素对这些集合进行分类。

数学家们为集合上二元操作符的每种可能行为都规定了专门的术语。作为应用型程序员,我们最主要关注的是群(Group,源自群论),但让我们循序渐进地了解它。在这个庞大的代数动物园中,群只是其中的一种。因此,与其孤立地研究群,不如将其放在相关的代数结构(即带有二元操作符的集合)的大背景下进行研究。

抽象代数是一个极其庞大的领域,但我们此处的目的是清晰地理解什么是 群 ,因为在零知识证明(Zero Knowledge Proofs)中它无处不在。我们现在就可以给出一个定义:

群是一个带有二元操作符的集合,该操作符满足封闭性、结合律,具有单位元,且每个元素都有一个逆元。

<aside> 💡 💡 一句话理解:这一长串定义其实是『四道门槛』,从松到严层层加码。最宽松的叫原群(只要算完不跑出集合),加上『结合律』变半群,再加个『不起作用的元素(单位元)』变幺半群,最后再要求『人人都有反操作(逆元)』就成了群。后面会一关一关讲,现在记住群是要求最严的那个就行。

</aside>

但这种简练的定义往往不够具有启发性。将其与更广泛的抽象代数领域联系起来理解会更有帮助。

原群 (Magma)

原群(Magma)是一个具有封闭二元操作符的集合。仅此而已。

<aside> 💡 💡 打个比方:『封闭』就像一个只进不出的房间——你拿房间里的两样东西做运算,结果还得乖乖待在房间里。比如整数加整数永远是整数($3+5=8$),不会突然蹦出个分数。原群的唯一要求就是这个,别的什么都不管。

</aside>

作为一个程序员,你凭借直觉绝对能理解原群。现在你只是知道了它的专业名称。

例如,考虑所有正整数的集合,我们的二元操作符是 $x^y$ 。注意我们不允许有负数,因为如果 $y$ 为负数,我们就会得到分数。

很明显,输出结果必定在整数空间内。我们的函数是 $(\mathbb{Z}\times\mathbb{Z})$ 和 $\mathbb{Z}$ 的笛卡尔积(关系)的一个子集。具体而言, $x^y$ 是一个从 $(\mathbb{Z}\times\mathbb{Z})$ 映射到 $\mathbb{Z}$ 的函数。

<aside> 💡 💡 这串符号别被吓到:$\mathbb{Z}\times\mathbb{Z}$ 就是『任挑两个整数配成一对』,比如 $(3,2)$。而 $x^y$ 就是一台机器,喂进去一对 $(3,2)$,吐出来一个整数 $3^2=9$。所谓『从 $\mathbb{Z}\times\mathbb{Z}$ 映到 $\mathbb{Z}$』,无非是说:进去是一对数,出来是一个数,仅此而已。

</aside>

有趣的是,这个例子既不满足交换律,也不满足结合律。你可以通过在下面的 Python 代码中为 a 、 b 和 c 选择不同的值来亲自验证这一点。

assert a ** (b ** c) != (a ** b) ** c
assert a ** b != b ** a

但我们并不在乎这一点。原群(Magma)是限制最少的 代数结构 之一。唯一重要的是其二元操作符必须具有封闭性。至于其他特性则均不做要求。

代数结构 指的是一个带有在该集合上定义的一系列操作的集合。在我们的讨论范围内,我们唯一关心的操作就是二元操作符。

半群 (Semigroup)

半群(Semigroup)是一种二元操作符必须满足结合律的原群(Magma)。