Skip to content

Commit 36b6fa0

Browse files
committed
Enhance surreal.md by adding a Python implementation of Surreal Numbers
1 parent bce9652 commit 36b6fa0

File tree

2 files changed

+96
-4
lines changed

2 files changed

+96
-4
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ public/
77
.deploy*/
88
_multiconfig.yml
99
.vscode
10-
*.py
10+
*.py
11+
__pycache__

source/_posts/surreal.md

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,99 @@ $$
8080

8181
由于等号 $=$ 的特殊性,需要指出,这里的等号意义比“相等”要弱一些,具体表现在,我们可以构造一种运算 $f$,使得 $x=y$ 与 $f\left(x\right)=f\left(y\right)$ 不等价。
8282

83-
因此,我们规定,定义变量的时候,使用 $:=$ 表示赋值/定义;使用 $\equiv$ 表示两个数的 $L$ 和 $R$ 分别相等(递归定义,这时若 $x\equiv y$,则显然可以将式子中的一切 $y$ 替换为 $x$)。
83+
因此,我们规定,定义变量的时候,使用 $:=$ 表示赋值/定义;使用 $\equiv$ 表示两个数的 $L$ 和 $R$ 分别相等(称为全等/恒等,递归定义,这时若 $x\equiv y$,则显然可以将式子中的一切 $y$ 替换为 $x$)。
84+
85+
{% note code open %}
86+
这里使用 Python(3.13) 编写了一个简单的 Surreal Number 的类,对象不可变,支持了 $\geqslant,\leqslant,+,-,\times$(`__ge__`, `__le__`, `__add__`, `__neg__`, `__sub__`, `__mul__`);可以使用 `is` 运算判断两个数全等。
87+
88+
由于 Python hashable 对象的相关 feature,定义 `__eq__` 为 $=$ 会导致一些冲突,而定义 `__eq__` 为 $\equiv$(`is`)会导致歧义;故不定义 `__eq__` 方法。
89+
90+
由于定义数的名称的困难,打印时的基本单元为 `{ | }`
91+
92+
方便验证一些数的大小关系。
93+
94+
```python
95+
# pylint: disable=invalid-name
96+
97+
"""Surreal Numbers"""
98+
99+
from __future__ import annotations
100+
101+
from functools import lru_cache
102+
103+
104+
class SurrealNumber:
105+
"""A surreal number represented by two sets of surreal numbers."""
106+
107+
No: dict[str, SurrealNumber] = {}
108+
L: frozenset[SurrealNumber]
109+
R: frozenset[SurrealNumber]
110+
111+
@staticmethod
112+
@lru_cache(maxsize=1 << 24)
113+
def to_string(
114+
left: frozenset[SurrealNumber],
115+
right: frozenset[SurrealNumber],
116+
) -> str:
117+
"""Convert the surreal number to a string representation."""
118+
left_str = ", ".join(sorted(repr(x) for x in left))
119+
right_str = ", ".join(sorted(repr(x) for x in right))
120+
return f"{{{left_str} | {right_str}}}"
121+
122+
def __new__(
123+
cls,
124+
left: frozenset[SurrealNumber] = frozenset(),
125+
right: frozenset[SurrealNumber] = frozenset(),
126+
) -> SurrealNumber:
127+
"""Create a new surreal number or return an existing one."""
128+
key = cls.to_string(frozenset(left), frozenset(right))
129+
if key not in cls.No:
130+
instance = super().__new__(cls)
131+
instance.L = frozenset(left)
132+
instance.R = frozenset(right)
133+
cls.No[key] = instance
134+
return cls.No[key]
135+
136+
def __ge__(self, other: SurrealNumber) -> bool:
137+
"""Check if this surreal number is greater than or equal to another."""
138+
return not any(right <= other for right in self.R) and not any(left >= self for left in other.L)
139+
140+
def __le__(self, other: SurrealNumber) -> bool:
141+
"""Check if this surreal number is less than or equal to another."""
142+
return other >= self
143+
144+
def __add__(self, other: SurrealNumber) -> SurrealNumber:
145+
"""Add two surreal numbers."""
146+
return SurrealNumber(
147+
{xL + other for xL in self.L} | {self + yL for yL in other.L},
148+
{xR + other for xR in self.R} | {self + yR for yR in other.R},
149+
)
150+
151+
def __neg__(self) -> SurrealNumber:
152+
"""Negate the surreal number."""
153+
return SurrealNumber({-x for x in self.R}, {-x for x in self.L})
154+
155+
def __sub__(self, other: SurrealNumber) -> SurrealNumber:
156+
"""Subtract two surreal numbers."""
157+
return self + (-other)
158+
159+
def __mul__(self, other: SurrealNumber) -> SurrealNumber:
160+
"""Multiply two surreal numbers."""
161+
L1 = {xL * other + self * yL - xL * yL for xL in self.L for yL in other.L}
162+
L2 = {xR * other + self * yR - xR * yR for xR in self.R for yR in other.R}
163+
R1 = {xL * other + self * yR - xL * yR for xL in self.L for yR in other.R}
164+
R2 = {xR * other + self * yL - xR * yL for xR in self.R for yL in other.L}
165+
return SurrealNumber(L1 | L2, R1 | R2)
166+
167+
def __repr__(self) -> str:
168+
"""Return a string representation of the surreal number."""
169+
return self.to_string(self.L, self.R)
170+
171+
def __str__(self) -> str:
172+
"""Return a string representation of the surreal number."""
173+
return self.__repr__()
174+
```
175+
{% endnote %}
84176

85177
## 超限归纳
86178

@@ -410,8 +502,7 @@ $$
410502
\begin{align\*}
411503
\tag{i} x,y\in\mathbf{No} &\Rightarrow xy\in\mathbf{No} \\\\
412504
\tag{ii} x\_1=x\_2 &\Rightarrow x\_1y=x\_2y \\\\
413-
\tag{iii} x\_1\leqslant x\_2\land y\_1\leqslant y\_2 &\Rightarrow x\_1y\_2+x\_2y\_1\leqslant x\_1y\_1+x\_2y\_2 \\\\
414-
\tag{iv} x\_1\not\geqslant x\_2\land y\_1\not\geqslant y\_2 &\Rightarrow x\_1y\_2+x\_2y\_1\not\geqslant x\_1y\_1+x\_2y\_2 \\\\
505+
\tag{iii} x\_1\leqslant x\_2\land y\_1\leqslant y\_2 &\Rightarrow x\_1y\_2+x\_2y\_1\leqslant x\_1y\_1+x\_2y\_2
415506
\end{align\*}
416507
$$
417508

0 commit comments

Comments
 (0)