书接上回,我们考虑如何构造这个游戏。这里就是研究如何构造一个7阶的Finite Projective Plane。这篇的内容,大量参考 The what, how and why of Finite projective planes。然后我又找到了一个更好的视频资料:Module 4: Projective and Affine Planes。
非欧几何
欧氏几何通过5条公理推演了一个系统,其中第五条公理可以导出平行公理(这块资料请参考维基百科: 欧几里得几何)。让我们来看看下面的图:

这图是我的Chrome浏览器的主题背景。我们可以看到,这些现实生活中平行的铁轨,让人感觉起来会相交在遥远的地方。我们能否得到和欧几里得几何不一样的几何系统呢?比如,平行线会在遥远的(无穷远处)相交。
几何还是研究点(Point)和线(Line),线是点的集合。约定下面三个基本公理(Incidence Axioms):
- 两个不同的点,唯一的确定一条线:\forall p_1,p_2 \in \mathcal{P}, p_1 \ne p_2 \implies \exists! l \in \mathcal{L}, p_1 \in l \land p_2 \in l 。
- 一条线上最少得有两个不同的点:\forall l\in \mathcal{L}, \exists p_1, p_2 \in \mathcal{P}, p_1 \ne p_2 \land p_1 \in l \land p_2 \in l。
- 存在不共线的三个不同的点:\exists p_1,p_2,p_3 \in \mathcal{P}, (p_1 \ne p_2 \land p_1 \ne p_3 \land p_1 \ne p_3) \implies (\nexists l \in \mathcal{L}, p_1 \in l \land p_2 \in l \land p_3 \in l) 。
然后再考虑集中不同的“平行”:
- 椭圆平行(
Elliptic Parallel):\forall l \in \mathcal{L}, \forall p \in \mathcal{P}, p \notin l \implies (\nexists l' \in \mathcal{L}, p \in l' \land l' \parallel l ) - 欧几里得平行(
Euclidean Parallel): \forall l \in \mathcal{L}, \forall p \in \mathcal{P}, p \notin l \implies (\exists! l' \in \mathcal{L}, p \in l' \land l' \parallel l ) - 双曲线平行(
Hyperbolic Parallel):这里我们暂时不关心。
平行的含义就是两条线没有共同点:l_1, l_2 \in \mathcal{L}, l_1 \ne l_2, l_1 \parallel l_2 \iff (\nexists p \in \mathcal{P}, p \in l_1 \land p \in l_2)。
基于上面的Incidence Axioms(或者加强版本),选择不同的平行,可以得到不同的集合系统:Affine Plane和Projective Plane。
Affine Plane
基于Incidence Axioms和Euclidean Parallel,我们可以得到一个集合系统,称为Affine Plane。Affine Plane严格一点的定义为:点集合\mathcal{P},线集合\mathcal{L},任何一条线是一个点的集合,且满足下面的全部要求:
Incidence Axioms1: 两不同的点唯一确定一条直线。Incidence Axioms2: 一条线上最少有两个不同的点。Incidence Axioms3:存在三个不同的点,它们不共线。:给定任何一条线,和一个点,如果这个点不在这条线上,那么存在且只存在唯一的一条线,通过这个点且和给定的线平行。Euclidean Parallel

上面的示意图是一个含有4个点的Affine Plane:
- \mathcal{P} = \{A,B,C,D\}
- \mathcal{L} = \{\overline{AB}, \overline{AC}, \overline{AD}, \overline{BC},\overline{BD}, \overline{CD} \}
- 平行的簇:
- [\overline{AB}] = \{\overline{AB}, \overline{CD}\}
- [\overline{AC}] = \{\overline{AC}, \overline{BD}\}
- [\overline{BC}] = \{\overline{BC}, \overline{AD}\}
可以证明,这里的平行,是一个等价关系。它可以定义等价类,并且对一个Affine Plane里的所有线进行划分。
给定一个Affine Plane,我们找出它所有的平行的簇(即所有等价类,基于平行这个等价关系的)。假设每个等价类,产生一个point,这些如此诞生的points称之为points at infinity。再引入一条新的线,叫做line at infinity,它就是包含且仅仅包含刚刚新诞生的那些points at infinity。然后我们需要对新加入的点和线的归属关系,做一些定义,为,如果一个新加入的p point at infinity是由于平行等价类[l] = \{l_1,l_2,\dots\}产生的,那么\forall l' \in [l], p \in l'; \forall l' \notin [l], p \notin l'。这种操作实际上就是模拟了之前的图片,我们让平行线都汇聚在某个无穷远的点。经过这种加点加线和赋予了新点的从属关系后,我们得到了一个新的几何系统,称之为Projective Plane。
Projective Plane
点集和线集,然后满足加强版的Incidence Axioms(加强第二条),以及选择Elliptic Parallel,得到的几何系统叫做Projective Plane:
Incidence Axioms1: 两不同的点唯一确定一条直线。- 加强版
Incidence Axioms2: 一条线上最少有3个不同的点。 Incidence Axioms3:存在三个不同的点,它们不共线。Elliptic Parallel:给定一个线和一个点,如果这个点不在这条线上,则不存在一条通过这个点的线和给定的线平行。
我们先看上面的Affine Plane用加点加线办法得到的新系统是一个Projective Plane。用4个点的Affine Plane做例子:
- 新的点集合是两部分:\mathcal{P} = \mathcal{P}_{\text{affine}} \cup \mathcal{P}_{\text{infinity}} = \{A,B,C,D\} \cup \{P_{[\overline{AB}]}, P_{[\overline{AC}]}, P_{[\overline{BC}]}\}
- 新的线集合也是两部分:\mathcal{L} = \mathcal{L}_{\text{affine}} \cup \{l_{\text{infinity}}\}= \{\overline{AB}, \overline{AC}, \overline{AD}, \overline{BC},\overline{BD}, \overline{CD} \} \cup \{\overline{P_{[\overline{AB}]} P_{[\overline{AC}]} P_{[\overline{BC}]}}\}
为了方便描述,我们给新家的点重新取名: P_{[\overline{AB}]} \iff E, P_{[\overline{AC}]} \iff F, P_{[\overline{BC}]} \iff G ,则新的几何系统的点和线为:
- \mathcal{P} = \{A,B,C,D,E,F,G\}
- \mathcal{L} = \{\overline{ABE}, \overline{ACF}, \overline{ADG}, \overline{BCG}, \overline{BDF}, \overline{CDE}, \overline{EFG} \}
下面的程序验证了这是一个Projective Plane:
create language plpython3u;
CREATE LANGUAGE
create table points(p text);
CREATE TABLE
create table lines(l text[]);
CREATE TABLE
insert into points
values ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G');
INSERT 0 7
insert into lines
values ('{A,B,E}'),
('{A,C,F}'),
('{A,D,G}'),
('{B,C,G}'),
('{B,D,F}'),
('{C,D,E}'),
('{E,F,G}');
INSERT 0 7
with
pairs(x, y) as (select p1.p, p2.p from points p1, points p2 where p1.p < p2.p),
npoints(n) as (select count(p) from points)
select (select count(1) from
(select
x, y, array_agg(l) as ls
from pairs, lines
where x = any (l) and y = any(l)
group by 1,2
having array_length(array_agg(l), 1) = 1
)s) as cnt1,
(select (n*(n-1)/2)::int from npoints) as cnt2;
cnt1 | cnt2
------+------
21 | 21
(1 row)
select bool_and(array_length(l, 1) >= 3) from lines;
bool_and
----------
t
(1 row)
with
tripples(x, y, z) as (select p1.p, p2.p, p3.p from points p1, points p2, points p3 where p1.p < p2.p and p2.p < p3.p)
select * from tripples
where not exists (select 1 from lines where x = any(l) and y = any(l) and z = any(l));
x | y | z
---+---+---
A | B | C
A | B | D
A | C | D
B | C | D
A | C | E
A | D | E
B | C | E
B | D | E
A | B | F
A | D | F
A | E | F
B | C | F
B | E | F
C | D | F
C | E | F
D | E | F
A | B | G
A | C | G
A | E | G
A | F | G
B | D | G
B | E | G
B | F | G
C | D | G
C | E | G
C | F | G
D | E | G
D | F | G
(28 rows)
create function line_parallel(a text[], b text[]) returns boolean as
$$
sa = set(a)
sb = set(b)
return len(sa & sb) == 0
$$
language plpython3u;
CREATE FUNCTION
with point_line(p, l) as (select p, l from points, lines where not (p = any(l)))
select *
from point_line pl, lines ls
where pl.p = any(ls.l) and line_parallel(ls.l, pl.l);
p | l | l
---+---+---
(0 rows)
上面的系统称之为Fano Plane,可以参考资料 https://mathworld.wolfram.com/FanoPlane.html,一个可视化的图如下:
我们来证明用这种加点加线的算法,可以从一个Affine Plane得到一个Projective Plane。
Incidence Axioms1- 如果两个点都来自旧的
Affine Plane的点集合,那么自动继承了这个性质; - 如果两个点都来自新加的
points at infinity,那么它们确定且唯一确定了那一条新加的线line at infinity - 如果一个点p_1来自旧的,一个点p_2来自新的,那么包含p_2的所有线的集合是一个原来的
Affine Plane里线的平行等价类\mathcal{L}_{p_2} = \{l_1,l_2,\dots,l_n | l_1 \parallel l_2 \dots \parallel l_n\}, \forall l \in \mathcal{L}_{p_2}, p_2 \in l。- 情况1: \exists l \in \mathcal{L}_{p_2}, p_1 \notin l,则根据
Affine Plane的欧几里得平行,\exists! l', p_1 \in l' \land l' \parallel l,故而l' \in \mathcal{L}_{p_2},它就是那条由p_1,p_2唯一确定的线。 - 情况2: \forall l \in \mathcal{L}_{p_2}, p_1 \in l,这只有一种可能,就是|\mathcal{L}_{p_2}| = 1,这时候里面那条唯一的线就是由p_1,p_2唯一确定的线。
- 情况1: \exists l \in \mathcal{L}_{p_2}, p_1 \notin l,则根据
- 如果两个点都来自旧的
- 加强版
Incidence Axioms2:Affine Plane的每条线都都至少有两个点,这些线又都被赋予了新的点,所以对这些成立;- 考虑那条
line at infinity,由于Affine Plane的Incidence Axioms3,我们可以找到三个在Affine Plane里不共线的点p_1,p_2,p_3,这样就有三条线:\overline{p_1p_2}, \overline{p_2p_3}, \overline{p_1p_3}。这三条线来自三个不同的平行等价类,这也就意味着至少有三个不同等等价类,也就是line at infinity至少有三个点。
Incidence Axioms3:直接继承Affine Plane的Incidence Axioms3。- 椭圆平行性质:线有之前的线和
line at infinity两类,点有之前的点和points at infinity两类,合计四种情况讨论- 情况1:\forall l \in \{\text{Affine Plane的线集合}\}, \forall p \in \{\text{Affine Plane的点集合}\}, p \notin l,根据
Affine Plane平行性质,\exist! l', p \in l' \land l' \parallel l,那么这条唯一的线,会被加上同一个等价类衍生出的点,这样就无法平行了。 - 情况2: \forall l \in \{\text{Affine Plane的线集合}\}, \forall p \in \{\text{points at infinity}\}, p \notin l,这就意味着p所在的所有线,在
Affine Plane内,和l不平行,也就是有交点,那么现在更不可能平行。 - 情况3: \forall l = \text{line at infinity}, \forall p \in \{\text{Affine Plane的点集合}\}, p \notin l,l和其他所有的线都有交点,故而无法找到平行线。
- 情况4同3
- 情况1:\forall l \in \{\text{Affine Plane的线集合}\}, \forall p \in \{\text{Affine Plane的点集合}\}, p \notin l,根据
证明完毕。\square
更多关于Projective Plane的性质
给定一个Projective Plane,点集合是\mathcal{P},线集合是\mathcal{L},有一些有用的定理如下:
定理1:\forall l_1,l_2 \in \mathcal{L}, l_1 \ne l_2, \exists! p \in \mathcal{P}, p \in l_1 \land p \in l_2。
证明1:Incidence Axioms 1可以推理出l_1,l_2不可能有两个或者两个以上交点。根据椭圆平行原则,l_1,l_2必然有交点。故而存在且仅存在唯一的交点,证明完毕。\square
定理2:\forall p \in \mathcal{P}, \exists l \in \mathcal{L}\ p \notin l。
证明2:用反证法。具体步骤这里略去。
定理3:(\exists l \in \mathcal{L}, |l| = n+1) \implies (\forall l' \in \mathcal{L}, |l'|=n+1)。
证明3:l=\{p_1,p_2,\dots, p_{n+1}\};根据Incidence Axioms 2&3,\exists p \notin l,由于Incidence Axioms 1考虑下面的线集合\mathcal{L}_{p,l}=\{\overline{pp_1}, \overline{pp_2}, \dots, \overline{pp_{n+1}}\},易知\mathcal{L}_{p,l}里的n+1条线全部不同。
引理a: \mathcal{L}_{p,l}是所有包含p的线。用反证法证明这一点:假设还有一个线l^* \notin \mathcal{L}_{p,l}, p \in l^* ,根据定理1(两条不同的线有且只有一个交点),则 l^*, l 必然有一个交点p_i (i \in [1,n+1]),故而l^*=\overline{pp_i}(Incidence Axioms 1),这说明l^* \in \mathcal{L}_{p,l} ,矛盾。故而\mathcal{L}_{p,l}是所有包含p的线。至此我们得到了一个结论:\forall p \in \mathcal{P}, \forall l \in \mathcal{L}, (|l|=n+1 \land p \notin l) \implies |\mathcal{L}_{p,l}| = n + 1。(即: 任何含有n+1个点的线l,它外头的点,都存在且只存在于n+1条不同的线上)。
引理b:接下来我们继续证明一个结论:\forall p \in \mathcal{P}, (\mathcal{L}_{p} = \{l \in \mathcal{L} | p \in l\}, |\mathcal{L}_{p}| = n+1) \implies (\forall l \in \mathcal{l}, p \notin l, |l|=n+1)。也就是给定了任何一点,如果这个点在n+1条不同的线上,那么任何一条线如果不穿过给定的这个点都含有且只含有n+1个不同的点。下面开始证,给定一个满足条件的点p,所有穿过它的线的集合是\{l_1,l_2,\dots,l_{n+1}\}根据定理2,可以找到某条线l, p \notin l,根据定理1,我们可以得到一组点的集合\mathcal{P}_{l,p}=\{ p_1=l\cap l_1, p_2=l\cap l_2, \dots, p_{n+1}=l\cap l_{n+1} \}。容易证明(这里省略过程)这个集合\mathcal{P}_{l,p}是distinct的。假设还有一个额外的点p^* \in l \land p^* \notin \mathcal{P}_{l,p},则\overline{pp^*}是一条穿过p的线,则\overline{pp^*} \in \mathcal{L}_{p}, \exist j, \overline{pp^*} = l_j,那么p^* = l_j\cap l ,矛盾了。故而这个小结论获证。
接下来我们只需要找出来三个不同的点p_1,p_2,p_3,且它们不共线,并且这三个点都属于且属于n+1条线。只要找到了,这个定理就获证了。因为不共线,则\forall l \in \mathcal{L}, \exists p_i (1\le i \le 3), p_i \notin l。再利用上面的小结论,可以知道任何一条线都有且只有n+1个点。剩下的任务,就是找这么三个点。
回到定理的假设条件,l含有n+1个不同的点。结合Incidence Axioms 2&3,可以找到两个不同的点\alpha, \beta \notin l。对l用ncidence Axioms 2,可以找到其上两个不同的点\eta,\xi \in l。由引理1,\alpha, \beta分别各自都在n+1条线上;由引理2,除了\overline{\alpha\beta}这条线以外,其他任何线都有且只有n+1个点。再看\overline{\alpha\beta}, \overline{\alpha\eta}这两条线,它们必然是不同的线(Incidence Axioms 1),所以\beta \notin \overline{\alpha\eta},则\overline{\alpha\eta}必然包含n+1个点;进一步\xi \notin \overline{\alpha\eta},则\xi被包含且仅仅被包含于n+1条线。再有\xi \notin \overline{\alpha\beta},所以\overline{\alpha\beta}也含有且只含有n+1个点。故而定理得证。\square
定理4:(\exists l \in \mathcal{L}, |l|=n+1) \implies (\forall p \in \mathcal{P}, \mathcal{L}_p = \{l' \in \mathcal{L} | p \in l'\}, |\mathcal{L}_p|=n+1)。
证明4:略去。
定理5:(\exists l \in \mathcal{L}, |l|=n+1) \implies (|\mathcal{P}| = n^2+n+1 \land |\mathcal{L}| = n^2+n+1)。
证明5:给定先决条件后,由定理3&4可以知道这个Projective Plane的任何一条线都有且只有n+1个点,任何一个点都属于且只属于n+1条线。任意选定一个点p_0, \mathcal{L}_{p_0}=\{ l_1,l_2,\dots,l_{n+1} \}是n+1条覆盖p_0的线。则这个系统里,任何一个点,\forall p \in \mathcal{P}, p \ne p_0,对应的直线\overline{pp_0}必然有 \overline{pp_0} \in \mathcal{L}_{p_0} ,也就说系统里任何一个点都在上面的n+1条线里。那么这个系统里的点的总数就是(n+1)^2 - p_0\text{多算的次数} = (n+1)^2 - n = n^2+n+1。两点确定一条线,则线数目{n^2+n+1 \choose 2},然后一条线上有n+1个点,意味着上面数字里每一条线都算成了{n+1 \choose 2},所以系统里的总线数目是 {n^2+n+1 \choose 2} / {n+1 \choose 2} = n^2+n+1 。\square
阶数的定义(the order of a finiate projective plane):(\exists l \in \mathcal{L}, |l| = n + 1) \implies \text{the order of this projective plane is }n。如果从一个Affine Plane通过前面的加线、加点技术得到了一个n阶的finiate projective plane,那么这个Affine Plane共有 n^2+n+1 - 1 = n^2+n 条线, n^2+n+1 - (n+1) = n^2 个点。
构造一个素数阶p的Finite Projective Plane
p是素数,构造的算法是先构造p^2个点,p^2+p条线的Affine Plane,然后再通过加线、加点的办法就可以得到一个p阶的finiate projective plane。p是素数,那么\mathbb{Z}_p是一个有限域,记作\mathbb{F}_p, \oplus = \lambda \ x \ y: (x + y) \mod p, \ast = \lambda \ x \ y: (xy) \mod p。基于这个有限域构造一个二位的向量空间是:V = \mathbb{F}^2_p。这个二位向量空间的元素数目(点)是p^2。所以我们得到了要构造的Affine Plane的所有点。
接下来就是构造出线,需要 p^2+p 条。线不过是点的集合,我们用方程的解集来描述点的集合,如下:
a,b,c \in \mathbb{F}_p, \{(x,y) \in V | (a\ast x) \oplus (b\ast y) = c\}注意到a=0,b=0时只有c=0才行,但这并不能表示线,所以需要剔除这种情况。且还注意到方程两边同时乘以同一个常数,不改变线的内容。所以我们用三元组[a,b,c]表示线为:k\ast (a\ast x)\oplus k\ast (b\ast y) = k\ast c, \forall k\in \mathbb{F}_p \land k \ne 0。
我们用4点Affine Plane来试试手:
- 选择素数2,则\mathbb{F}_2 = \{0, 1\}, V = \{(0,0), (0,1), (1,0), (1,1)\}
- 做点的名字映射A=(0,0), B=(0,1), C=(1,0), D=(1,1)
- 罗列所有可能的线:
- [0,1,0] \implies y = 0 \implies \{(0,0), (1,0)\} = \overline{AC}
- [0,1,1] \implies y = 1 \implies \{(0,1), (1,1)\} = \overline{BD}
- [1,0,0] \implies x = 0 \implies \{(0,0), (0,1)\} = \overline{AB}
- [1,0,1] \implies x = 1 \implies \{(1,0), (1,1)\} = \overline{CD}
- [1,1,0] \implies x \oplus y=0 \implies \{(0,0), (1,1)\} = \overline{AD}
- [1,1,1] \implies x \oplus y= 1 \implies \{(0,1), (1,0)\}=\overline{BC}
- 这恰好就是4点
Affine Plane - 平行等价类:
- [0,1,0] \parallel [0,1,1]
- [1,0,0] \parallel [1,0,1]
- [1,1,0] \parallel [1,1,1]
我们再看一个素数3例子:
- \mathbb{F}_{3} = \{0,1,2\} , V=\{A=(0,0), B=(0,1), C=(0,2), D=(1,0),E=(1,1), F=(1,2), G=(2,0),H=(2,1), I=(2,2)\}, |V|=3^2=9
- 罗列所有的线:
- [0,1,0] \implies y=0 \implies \{(0,0), (1,0), (2,0)\} = \overline{ADG}
- [0,1,1] \implies y=1 \implies \{(0,1),(1,1), (2,1)\} = \overline{BEH}
- [0,1,2] \implies y = 2 \implies \{(0,2),(1,2),(2,2)\} = \overline{CFI}
- [0,2,0] \implies 2\ast y=0 \implies y = 0,同 [0,1,0]
- [0,2,1] \implies 2\ast y=1 \implies y = 2,同 [0,1,2]
- [0,2,2] \implies 2\ast y = 2 \implies y = 1, 同[0,1,1]
- [1,0,0] \implies x =0 \implies \{(0,0), (0,1), (0,2)\} = \overline{ABC}
- [1,0,1] \implies x = 1 \implies \{(1,0),(1,1),(1,2)\} = \overline{DEF}
- [1,0,2] \implies x = 2 \implies \{(2,0),(2,1),(2,2)\} = \overline{GHI}
- [1,1,0] \implies x\oplus y = 0 \implies \{(1,2), (2,1), (0,0)\} = \overline{AFH}
- [1,1,1] \implies x\oplus y = 1 \implies \{(0,1), (1,0), (2,2)\} = \overline{BDI}
- [1,1,2] \implies x\oplus y = 1 \implies \{(0,2), (1,1), (2,0)\} = \overline{CEG}
- [1,2,0]\implies x\oplus 2\ast y = 0 \implies \{(0,0), (1,1),(2,2)\} = \overline{AEI}
- [1,2,1] \implies x\oplus 2\ast y = 1 \implies \{(0,2), (1,0), (2,1)\} = \overline{CDH}
- [1,2,2] \implies x\oplus 2\ast y = 2 \implies \{(0,1), (1,2), (2,0)\} = \overline{BFG}
- [2,0,0] \implies 2\ast x = 0 \implies x = 0,同[1,0,0]
- [2,0,1] \implies 2\ast x = 1 \implies x = 2,同[1,0,2]
- [2,0,2] \implies 2\ast x= 2 \implies x = 1,同[1,0,1]
- [2,1,0]\implies 2\ast x \oplus y = 0 \implies 4\ast x \oplus 2\ast y = 0 \implies x \oplus 2\ast y = 0 ,同[1,2,0]
- [2,1,1] \implies 2\ast x \oplus y = 1 \implies x \oplus 2\ast y = 2,同[1,2,2]
- [2,1,2] \implies 2\ast x \oplus y = 2 \implies x \oplus 2\ast y = 1,同 [1,2,1]
- [2,2,0] \implies 2\ast x \oplus 2\ast y = 0 \implies x\oplus y = 0,同[1,1,0]
- [2,2,1] \implies 2\ast x \oplus 2\ast y = 1 \implies x\oplus y = 2,同[1,1,2]
- [2,2,2] \implies 2\ast x \oplus 2\ast y = 2 \implies x\oplus y = 1,同[1,1,1]
- 合计12=3^2+3条不同的线,恰好吻合
Affine Plane。
看起来用这种办法就可以构造出一个Affine Plane了,然后再构造Finite Projective Plane不过是举手之劳而已了。对线的构造,我们需要做一些数学证明,证明算法是有效的。
素数阶Affine Plane构造算法:
- 给定素数 p ,构造点集合为\mathcal{P} = \mathbb{F}^2_p
- 构造线集合\mathcal{L} = \{ [a,b,c] | a,b,c \in \mathbb{F}_p \} - \{[0,0,c] | c \in \mathbb{F}_p\}
线集合里任何一个[a,b,c],和它一样的有p-1个,分别是 [a,b,c], [2\ast a, 2\ast b, 2\ast c], \dots, [(p-1)\ast a, (p-1) \ast b, (p-1) \ast c]。这样构造出来的线总数是:
\frac{p^3 - p}{p-1} = p(p+1) = p^2 + p- 验证
Incidence Axioms1, p_1=(x_1, y_1), p_2=(x_2,y_2), p_1 \ne p_2:- 如果x_1=x_2,那么这两个点锁定且唯一锁定的直线是x=x_1, [1,0,x_1]
- 如果x_1\ne x_2,可以锁定b=1,然后在\mathbb{F}_p上可以求出唯一的a,c。
- 验证
Incidence Axioms2,\mathbb{F}_2至少含有0,1,所以任何直线的方程,都至少有两个解(点)。 - 验证
Incidence Axioms3,任何这样的,都至少有三个点(0,1), (1,0), (0,0),它们是肯定不共线的(跳过验证)。 - 验证平行法则。(略去)
Python程序构造之前的对对碰
from sympy import isprime
from collections import defaultdict
n = input("请输入素数阶数n: ")
n = int(n)
if not isprime(n):
raise Exception("阶数%d不是素数" % n)
def plus(x, y):
return (x + y) % n
def mul(x, y):
return (x * y) % n
field = range(0,n)
points = [(i,j) for i in field for j in field]
lines = []
lines_set = set()
for i in field:
for j in field:
if i == 0 and j == 0: continue
for k in field:
if (i,j,k) in lines_set: continue
lines.append((i,j,k))
for m in range(1, n):
line = (mul(m,i), mul(m,j), mul(m,k))
lines_set.add(line)
def turn_line_to_pointset(line):
ps = set()
a,b,c = line
for x,y in points:
if plus(mul(a,x),mul(b,y)) == c:
ps.add((x,y))
return ps
lines_as_ps = [turn_line_to_pointset(line) for line in lines]
assert(all(len(ps) == n for ps in lines_as_ps))
point_name_map = dict([((x,y), i) for i, (x,y) in enumerate(points)])
point_names = list(range(len(points)))
lines = [set(point_name_map[p] for p in list(line)) for line in lines_as_ps]
parallel_eqs = dict()
eqs = set()
for i in range(len(lines)-1):
for j in range(i+1, len(lines)):
l1 = lines[i]
l2 = lines[j]
if len(l1 & l2) == 0: # l1 || l2
if i not in parallel_eqs:
parallel_eqs[i] = i
eqs.add(i)
parallel_eqs[j] = parallel_eqs[i]
rev_parallel_eqs = defaultdict(list)
for k, v in parallel_eqs.items():
rev_parallel_eqs[v].append(k)
n_new = len(eqs)
point_names = list(range(n_new+len(points)))
line_at_inf = set(list(range(len(points), len(points)+n_new)))
points_at_inf = list(line_at_inf)
eqs = list(eqs)
#points at inf加入到原来的线
for i, p in enumerate(points_at_inf):
eq = eqs[i]
lids = rev_parallel_eqs[eq]
for lid in lids:
lines[lid].add(p)
lines.append(line_at_inf)
def verify_project_plane(ps, ls):
#axiom 1: 两个不同点确定且唯一确定一条直线
for i in ps:
for j in ps:
if i == j: continue
if (sum(1 for l in ls if i in l and j in l) == 1) != 1:
print(i,j)
assert(0)
assert(sum(1 for l in ls if i in l and j in l) == 1)
#axiom 2: 每条线至少有3个不同点
assert(all(len(l) >= 3 for l in ls))
#axiom 3: 存在3个点,不共线
found = False
for i in ps:
if found: break
for j in ps:
if found: break
if i == j: continue
for k in ps:
if i == k or j == k: continue
found = sum(1 for l in ls if i in l and j in l and k in l) > 0
if found: break
assert(found)
#平行准则
for l in ls:
for p in ps:
if p in l: continue
assert(sum(1 for l2 in ls if p in l2 and len(l1 & l2) == 0) == 0)
#任何两条线交一点
assert(all(len(l1 & l2) == 1 for i, l1 in enumerate(ls) for j, l2 in enumerate(ls) if i != j))
print("验证通过!")
print("这个projective plane有%d个点, %d条线" % (len(point_names), len(lines)))
print(point_names)
print(lines)
verify_project_plane(point_names, lines)
生成的PG(2), PG(3), PG(7)如下:
gpadmin@zlyu-rr:~/zy$ python3 a.py
请输入素数阶数n: 2
这个projective plane有7个点, 7条线
[0, 1, 2, 3, 4, 5, 6]
[{0, 2, 4}, {1, 3, 4}, {0, 1, 5}, {2, 3, 5}, {0, 3, 6}, {1, 2, 6}, {4, 5, 6}]
验证通过!
gpadmin@zlyu-rr:~/zy$ python3 a.py
请输入素数阶数n: 3
这个projective plane有13个点, 13条线
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[{0, 9, 3, 6}, {1, 4, 9, 7}, {8, 9, 2, 5}, {0, 1, 2, 11}, {11, 3, 4, 5}, {8, 11, 6, 7}, {0, 12, 5, 7}, {8, 1, 3, 12}, {2, 4, 12, 6}, {8, 0, 10, 4}, {10, 2, 3, 7}, {1, 10, 5, 6}, {9, 10, 11, 12}]
验证通过!
gpadmin@zlyu-rr:~/zy$ python3 a.py
请输入素数阶数n: 7
这个projective plane有57个点, 57条线
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56]
[{0, 35, 7, 42, 14, 49, 21, 28}, {1, 36, 8, 43, 15, 49, 22, 29}, {2, 37, 9, 44, 16, 49, 23, 30}, {3, 38, 10, 45, 17, 49, 24, 31}, {32, 4, 39, 11, 46, 49, 18, 25}, {33, 5, 40, 12, 47, 49, 19, 26}, {34, 6, 41, 13, 48, 49, 20, 27}, {0, 1, 2, 3, 4, 5, 6, 51}, {7, 8, 9, 10, 11, 12, 13, 51}, {14, 15, 16, 17, 18, 19, 20, 51}, {51, 21, 22, 23, 24, 25, 26, 27}, {32, 33, 34, 51, 28, 29, 30, 31}, {35, 36, 37, 38, 39, 40, 41, 51}, {42, 43, 44, 45, 46, 47, 48, 51}, {0, 37, 43, 13, 19, 53, 25, 31}, {32, 1, 38, 7, 44, 20, 53, 26}, {33, 2, 39, 8, 45, 14, 53, 27}, {34, 3, 40, 9, 46, 15, 21, 53}, {4, 41, 10, 47, 16, 53, 22, 28}, {35, 5, 11, 48, 17, 53, 23, 29}, {36, 6, 42, 12, 18, 53, 24, 30}, {0, 33, 36, 10, 46, 20, 55, 23}, {4, 7, 40, 43, 17, 55, 27, 30}, {1, 34, 37, 11, 14, 47, 55, 24}, {5, 8, 41, 44, 18, 21, 55, 31}, {2, 38, 12, 15, 48, 55, 25, 28}, {32, 35, 6, 9, 45, 19, 22, 55}, {3, 39, 42, 13, 16, 55, 26, 29}, {0, 38, 9, 47, 18, 56, 27, 29}, {34, 36, 5, 7, 45, 16, 56, 25}, {32, 3, 41, 43, 12, 14, 23, 56}, {1, 39, 10, 48, 19, 21, 56, 30}, {37, 6, 8, 46, 17, 56, 26, 28}, {33, 35, 4, 44, 13, 15, 24, 56}, {2, 40, 42, 11, 20, 22, 56, 31}, {0, 34, 39, 44, 12, 17, 50, 22}, {2, 7, 41, 46, 50, 19, 24, 29}, {4, 36, 9, 14, 48, 50, 26, 31}, {33, 6, 38, 11, 43, 16, 50, 21}, {1, 40, 13, 45, 18, 50, 23, 28}, {3, 35, 8, 47, 50, 20, 25, 30}, {32, 5, 37, 42, 10, 15, 50, 27}, {0, 41, 11, 45, 15, 52, 26, 30}, {33, 3, 37, 7, 48, 18, 52, 22}, {6, 40, 10, 44, 14, 52, 25, 29}, {32, 2, 36, 13, 47, 17, 52, 21}, {5, 39, 9, 43, 20, 52, 24, 28}, {1, 35, 12, 46, 16, 52, 27, 31}, {34, 4, 38, 8, 42, 19, 52, 23}, {32, 0, 40, 8, 16, 48, 54, 24}, {6, 39, 7, 47, 15, 54, 23, 31}, {5, 38, 13, 46, 14, 22, 54, 30}, {4, 37, 12, 45, 20, 21, 54, 29}, {3, 36, 11, 44, 19, 54, 27, 28}, {2, 35, 34, 10, 43, 18, 54, 26}, {1, 33, 9, 41, 42, 17, 54, 25}, {49, 50, 51, 52, 53, 54, 55, 56}]
验证通过!