|
80 | 80 |
|
81 | 81 | 由于等号 $=$ 的特殊性,需要指出,这里的等号意义比“相等”要弱一些,具体表现在,我们可以构造一种运算 $f$,使得 $x=y$ 与 $f\left(x\right)=f\left(y\right)$ 不等价。
|
82 | 82 |
|
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 %} |
84 | 176 |
|
85 | 177 | ## 超限归纳
|
86 | 178 |
|
|
410 | 502 | \begin{align\*}
|
411 | 503 | \tag{i} x,y\in\mathbf{No} &\Rightarrow xy\in\mathbf{No} \\\\
|
412 | 504 | \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 |
415 | 506 | \end{align\*}
|
416 | 507 | $$
|
417 | 508 |
|
|
0 commit comments