pythonic-peano-arithmetic 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pythonic_peano_arithmetic-0.3.0/LICENSE +21 -0
- pythonic_peano_arithmetic-0.3.0/PKG-INFO +240 -0
- pythonic_peano_arithmetic-0.3.0/README.md +213 -0
- pythonic_peano_arithmetic-0.3.0/peano/__init__.py +66 -0
- pythonic_peano_arithmetic-0.3.0/peano/algebraic_root.py +180 -0
- pythonic_peano_arithmetic-0.3.0/peano/integer.py +345 -0
- pythonic_peano_arithmetic-0.3.0/peano/natural_number.py +340 -0
- pythonic_peano_arithmetic-0.3.0/peano/polynomial.py +431 -0
- pythonic_peano_arithmetic-0.3.0/peano/py.typed +1 -0
- pythonic_peano_arithmetic-0.3.0/peano/rational.py +295 -0
- pythonic_peano_arithmetic-0.3.0/peano/utils.py +189 -0
- pythonic_peano_arithmetic-0.3.0/pyproject.toml +66 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018 Yusuke Hayashi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pythonic-peano-arithmetic
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Build arithmetic from Peano axioms and trace algebraic real roots
|
|
5
|
+
Keywords: arithmetic,education,mathematics,peano
|
|
6
|
+
Author: Yusuke Hayashi
|
|
7
|
+
Author-email: Yusuke Hayashi <yusuke8h@gmail.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Education
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Education
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Project-URL: Documentation, https://peano.yusuke-hayashi.com/en/
|
|
23
|
+
Project-URL: Homepage, https://peano.yusuke-hayashi.com/en/
|
|
24
|
+
Project-URL: Issues, https://github.com/yhay81/pythonic-peano-arithmetic/issues
|
|
25
|
+
Project-URL: Repository, https://github.com/yhay81/pythonic-peano-arithmetic
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# Pythonic Peano Arithmetic
|
|
29
|
+
|
|
30
|
+
An educational Python library that constructs natural numbers, integers,
|
|
31
|
+
rational numbers, and polynomials from simple definitions, then uses rational
|
|
32
|
+
intervals to study algebraic real roots.
|
|
33
|
+
|
|
34
|
+
The implementation is intentionally small and explicit. Its purpose is to make
|
|
35
|
+
the correspondence between a mathematical definition and executable Python
|
|
36
|
+
visible—not to compete with Python's built-in numeric types.
|
|
37
|
+
|
|
38
|
+
The interactive course runs entirely in the browser with Zensical and Pyodide:
|
|
39
|
+
|
|
40
|
+
- [English course](https://peano.yusuke-hayashi.com/en/)
|
|
41
|
+
- [日本語の教材](https://peano.yusuke-hayashi.com/)
|
|
42
|
+
|
|
43
|
+
## What you can observe
|
|
44
|
+
|
|
45
|
+
- natural numbers built from `0` and the successor operation;
|
|
46
|
+
- recursive definitions of addition and multiplication;
|
|
47
|
+
- integers as equivalence classes of pairs of natural numbers;
|
|
48
|
+
- rationals as equivalence classes of integer pairs;
|
|
49
|
+
- polynomials as finite coefficient sequences;
|
|
50
|
+
- Sturm sequences and bisection over rational isolating intervals;
|
|
51
|
+
- Python mechanisms that connect notation to implementation: special methods,
|
|
52
|
+
decorators, frozen dataclasses, coercion, and operator dispatch.
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
Python 3.10 or later is required.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install pythonic-peano-arithmetic
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
For repository development, install
|
|
63
|
+
[uv](https://docs.astral.sh/uv/) and run:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
git clone https://github.com/yhay81/pythonic-peano-arithmetic.git
|
|
67
|
+
cd pythonic-peano-arithmetic
|
|
68
|
+
make install
|
|
69
|
+
make check
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## A five-minute tour
|
|
73
|
+
|
|
74
|
+
### Natural numbers: follow the recursive definition
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from peano import natural_number
|
|
78
|
+
from peano.utils import config_log
|
|
79
|
+
|
|
80
|
+
config_log(log_level=4)
|
|
81
|
+
two = natural_number(2)
|
|
82
|
+
one = natural_number(1)
|
|
83
|
+
print(two + one)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The trace names the rule used at each step:
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
[addition: base] add(S(S(0)), 0) -> S(S(0))
|
|
90
|
+
[addition: recursive] add(S(S(0)), S(0)) -> S(add(S(S(0)), 0))
|
|
91
|
+
3
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
These two lines correspond directly to:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
n + 0 = n
|
|
98
|
+
n + S(m) = S(n + m)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Pass `locale="ja"` to `config_log` to show Japanese rule labels.
|
|
102
|
+
|
|
103
|
+
### Integers: equality of representatives
|
|
104
|
+
|
|
105
|
+
An integer is represented by a pair `(a, b)`, read as `a - b`. Different pairs
|
|
106
|
+
can represent the same integer:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from peano import integer
|
|
110
|
+
|
|
111
|
+
print(integer(3, 1) == integer(4, 2))
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The implementation checks the defining equivalence:
|
|
115
|
+
|
|
116
|
+
```text
|
|
117
|
+
(a, b) ~ (c, d) exactly when a + d = b + c
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Rationals: equality by cross multiplication
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from peano import rational
|
|
124
|
+
|
|
125
|
+
print(rational(1, 2) == rational(2, 4))
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
This follows the definition `p/q ~ r/s` exactly when `p*s = q*r`.
|
|
129
|
+
|
|
130
|
+
### Algebraic real roots: approach √2 with rational intervals
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from peano import Polynomial, Q_ONE, Q_ZERO, algebraic_root, rational
|
|
134
|
+
|
|
135
|
+
x_squared_minus_two = Polynomial(rational(-2, 1), Q_ZERO, Q_ONE)
|
|
136
|
+
root = algebraic_root(x_squared_minus_two, (1, 1), (2, 1))
|
|
137
|
+
|
|
138
|
+
for interval in root.trace(5):
|
|
139
|
+
print(interval)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Every endpoint remains rational. The intervals are nested, their widths halve,
|
|
143
|
+
and each interval still isolates the positive root of `x² - 2`.
|
|
144
|
+
|
|
145
|
+
## Definition-to-implementation map
|
|
146
|
+
|
|
147
|
+
| Mathematical idea | Python implementation |
|
|
148
|
+
| --- | --- |
|
|
149
|
+
| zero and successor `S(n)` | `NaturalNumber`, `successor` |
|
|
150
|
+
| `0` differs from every successor | `NaturalNumber.__eq__` |
|
|
151
|
+
| successor is injective | `NaturalNumber.__eq__` |
|
|
152
|
+
| `n + 0 = n`, `n + S(m) = S(n + m)` | `NaturalNumber.__add__` |
|
|
153
|
+
| `n × 0 = 0`, `n × S(m) = n + n × m` | `NaturalNumber.__mul__` |
|
|
154
|
+
| `(a,b) ~ (c,d) ↔ a+d=b+c` | `Integer.__eq__` |
|
|
155
|
+
| `p/q ~ r/s ↔ ps=qr` | `Rational.__eq__` |
|
|
156
|
+
| coefficient sequence `(a₀,a₁,...)` | `Polynomial` |
|
|
157
|
+
| distinct roots in an interval | `sturm_sequence`, `count_real_roots` |
|
|
158
|
+
| one algebraic root | `AlgebraicRoot`, `RationalInterval` |
|
|
159
|
+
|
|
160
|
+
Mathematical induction is a proof principle, not a test performed by Python.
|
|
161
|
+
The finite tests check representative laws and guard the intended mapping
|
|
162
|
+
between the definitions and code.
|
|
163
|
+
|
|
164
|
+
## Logging
|
|
165
|
+
|
|
166
|
+
Operations return ordinary values. Internally, selected methods return a value
|
|
167
|
+
and a lazily constructed explanation; the `@log` decorator exposes only the
|
|
168
|
+
value and emits the explanation when logging is enabled.
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from peano.utils import config_log
|
|
172
|
+
|
|
173
|
+
config_log(
|
|
174
|
+
log_level=4,
|
|
175
|
+
max_lines=200,
|
|
176
|
+
# fmt="Level %(levelno)s: %(message)s", # expose internal levels if needed
|
|
177
|
+
)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Lower log levels reveal more detail. The numeric levels are an internal filter,
|
|
181
|
+
so the default display emphasizes rule names instead.
|
|
182
|
+
|
|
183
|
+
## Numeric tower and canonical forms
|
|
184
|
+
|
|
185
|
+
Mixed operations promote values through:
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
NaturalNumber → Integer → Rational → Polynomial
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Canonicalization keeps equivalent representatives predictable:
|
|
192
|
+
|
|
193
|
+
- `Integer.normalize()` moves a pair toward `(a-b, 0)` or `(0, b-a)`;
|
|
194
|
+
- `Rational.reduction()` makes the denominator positive and divides by the GCD;
|
|
195
|
+
- `Polynomial` removes trailing zero coefficients.
|
|
196
|
+
|
|
197
|
+
Equal values have equal hashes even when represented at different levels of the
|
|
198
|
+
numeric tower.
|
|
199
|
+
|
|
200
|
+
## Scope and limits
|
|
201
|
+
|
|
202
|
+
This project favors definitions that can be read over efficient arithmetic.
|
|
203
|
+
Keep examples small:
|
|
204
|
+
|
|
205
|
+
| Operation | Suggested values |
|
|
206
|
+
| --- | --- |
|
|
207
|
+
| natural-number comparison/addition | 0–10 |
|
|
208
|
+
| natural-number multiplication/division/powers | 0–5 |
|
|
209
|
+
| integer, rational, and polynomial components | absolute values up to 5 |
|
|
210
|
+
| algebraic-root tracing | roughly 12 bisections |
|
|
211
|
+
|
|
212
|
+
`AlgebraicRoot` is deliberately not a complete algebraic-number type. It
|
|
213
|
+
validates one isolated root and shrinks its rational interval, but provides no
|
|
214
|
+
arithmetic between roots and no general mathematical equality.
|
|
215
|
+
|
|
216
|
+
For interval refinement, sign checks use Python's arbitrary-precision integer
|
|
217
|
+
ratios internally. This preserves exactness while avoiding enormous
|
|
218
|
+
intermediate Peano representations; returned endpoints are still `Rational`.
|
|
219
|
+
|
|
220
|
+
## Documentation development
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
make docs # build Japanese at / and English at /en/
|
|
224
|
+
make docs-serve # preview Japanese
|
|
225
|
+
make docs-serve-en # preview English
|
|
226
|
+
make docs-a11y # run WCAG checks on both languages
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The site is deployed from `main` to Cloudflare Workers Static Assets. Deployment
|
|
230
|
+
requires `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` repository secrets.
|
|
231
|
+
|
|
232
|
+
## Release
|
|
233
|
+
|
|
234
|
+
Releases are built by GitHub Actions and published to PyPI with OpenID Connect.
|
|
235
|
+
The `pypi` GitHub environment must be registered as a PyPI Trusted Publisher
|
|
236
|
+
for this repository and `.github/workflows/publish.yml`.
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Pythonic Peano Arithmetic
|
|
2
|
+
|
|
3
|
+
An educational Python library that constructs natural numbers, integers,
|
|
4
|
+
rational numbers, and polynomials from simple definitions, then uses rational
|
|
5
|
+
intervals to study algebraic real roots.
|
|
6
|
+
|
|
7
|
+
The implementation is intentionally small and explicit. Its purpose is to make
|
|
8
|
+
the correspondence between a mathematical definition and executable Python
|
|
9
|
+
visible—not to compete with Python's built-in numeric types.
|
|
10
|
+
|
|
11
|
+
The interactive course runs entirely in the browser with Zensical and Pyodide:
|
|
12
|
+
|
|
13
|
+
- [English course](https://peano.yusuke-hayashi.com/en/)
|
|
14
|
+
- [日本語の教材](https://peano.yusuke-hayashi.com/)
|
|
15
|
+
|
|
16
|
+
## What you can observe
|
|
17
|
+
|
|
18
|
+
- natural numbers built from `0` and the successor operation;
|
|
19
|
+
- recursive definitions of addition and multiplication;
|
|
20
|
+
- integers as equivalence classes of pairs of natural numbers;
|
|
21
|
+
- rationals as equivalence classes of integer pairs;
|
|
22
|
+
- polynomials as finite coefficient sequences;
|
|
23
|
+
- Sturm sequences and bisection over rational isolating intervals;
|
|
24
|
+
- Python mechanisms that connect notation to implementation: special methods,
|
|
25
|
+
decorators, frozen dataclasses, coercion, and operator dispatch.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
Python 3.10 or later is required.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install pythonic-peano-arithmetic
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
For repository development, install
|
|
36
|
+
[uv](https://docs.astral.sh/uv/) and run:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/yhay81/pythonic-peano-arithmetic.git
|
|
40
|
+
cd pythonic-peano-arithmetic
|
|
41
|
+
make install
|
|
42
|
+
make check
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## A five-minute tour
|
|
46
|
+
|
|
47
|
+
### Natural numbers: follow the recursive definition
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from peano import natural_number
|
|
51
|
+
from peano.utils import config_log
|
|
52
|
+
|
|
53
|
+
config_log(log_level=4)
|
|
54
|
+
two = natural_number(2)
|
|
55
|
+
one = natural_number(1)
|
|
56
|
+
print(two + one)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The trace names the rule used at each step:
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
[addition: base] add(S(S(0)), 0) -> S(S(0))
|
|
63
|
+
[addition: recursive] add(S(S(0)), S(0)) -> S(add(S(S(0)), 0))
|
|
64
|
+
3
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
These two lines correspond directly to:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
n + 0 = n
|
|
71
|
+
n + S(m) = S(n + m)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Pass `locale="ja"` to `config_log` to show Japanese rule labels.
|
|
75
|
+
|
|
76
|
+
### Integers: equality of representatives
|
|
77
|
+
|
|
78
|
+
An integer is represented by a pair `(a, b)`, read as `a - b`. Different pairs
|
|
79
|
+
can represent the same integer:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from peano import integer
|
|
83
|
+
|
|
84
|
+
print(integer(3, 1) == integer(4, 2))
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The implementation checks the defining equivalence:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
(a, b) ~ (c, d) exactly when a + d = b + c
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Rationals: equality by cross multiplication
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from peano import rational
|
|
97
|
+
|
|
98
|
+
print(rational(1, 2) == rational(2, 4))
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
This follows the definition `p/q ~ r/s` exactly when `p*s = q*r`.
|
|
102
|
+
|
|
103
|
+
### Algebraic real roots: approach √2 with rational intervals
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from peano import Polynomial, Q_ONE, Q_ZERO, algebraic_root, rational
|
|
107
|
+
|
|
108
|
+
x_squared_minus_two = Polynomial(rational(-2, 1), Q_ZERO, Q_ONE)
|
|
109
|
+
root = algebraic_root(x_squared_minus_two, (1, 1), (2, 1))
|
|
110
|
+
|
|
111
|
+
for interval in root.trace(5):
|
|
112
|
+
print(interval)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Every endpoint remains rational. The intervals are nested, their widths halve,
|
|
116
|
+
and each interval still isolates the positive root of `x² - 2`.
|
|
117
|
+
|
|
118
|
+
## Definition-to-implementation map
|
|
119
|
+
|
|
120
|
+
| Mathematical idea | Python implementation |
|
|
121
|
+
| --- | --- |
|
|
122
|
+
| zero and successor `S(n)` | `NaturalNumber`, `successor` |
|
|
123
|
+
| `0` differs from every successor | `NaturalNumber.__eq__` |
|
|
124
|
+
| successor is injective | `NaturalNumber.__eq__` |
|
|
125
|
+
| `n + 0 = n`, `n + S(m) = S(n + m)` | `NaturalNumber.__add__` |
|
|
126
|
+
| `n × 0 = 0`, `n × S(m) = n + n × m` | `NaturalNumber.__mul__` |
|
|
127
|
+
| `(a,b) ~ (c,d) ↔ a+d=b+c` | `Integer.__eq__` |
|
|
128
|
+
| `p/q ~ r/s ↔ ps=qr` | `Rational.__eq__` |
|
|
129
|
+
| coefficient sequence `(a₀,a₁,...)` | `Polynomial` |
|
|
130
|
+
| distinct roots in an interval | `sturm_sequence`, `count_real_roots` |
|
|
131
|
+
| one algebraic root | `AlgebraicRoot`, `RationalInterval` |
|
|
132
|
+
|
|
133
|
+
Mathematical induction is a proof principle, not a test performed by Python.
|
|
134
|
+
The finite tests check representative laws and guard the intended mapping
|
|
135
|
+
between the definitions and code.
|
|
136
|
+
|
|
137
|
+
## Logging
|
|
138
|
+
|
|
139
|
+
Operations return ordinary values. Internally, selected methods return a value
|
|
140
|
+
and a lazily constructed explanation; the `@log` decorator exposes only the
|
|
141
|
+
value and emits the explanation when logging is enabled.
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from peano.utils import config_log
|
|
145
|
+
|
|
146
|
+
config_log(
|
|
147
|
+
log_level=4,
|
|
148
|
+
max_lines=200,
|
|
149
|
+
# fmt="Level %(levelno)s: %(message)s", # expose internal levels if needed
|
|
150
|
+
)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Lower log levels reveal more detail. The numeric levels are an internal filter,
|
|
154
|
+
so the default display emphasizes rule names instead.
|
|
155
|
+
|
|
156
|
+
## Numeric tower and canonical forms
|
|
157
|
+
|
|
158
|
+
Mixed operations promote values through:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
NaturalNumber → Integer → Rational → Polynomial
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Canonicalization keeps equivalent representatives predictable:
|
|
165
|
+
|
|
166
|
+
- `Integer.normalize()` moves a pair toward `(a-b, 0)` or `(0, b-a)`;
|
|
167
|
+
- `Rational.reduction()` makes the denominator positive and divides by the GCD;
|
|
168
|
+
- `Polynomial` removes trailing zero coefficients.
|
|
169
|
+
|
|
170
|
+
Equal values have equal hashes even when represented at different levels of the
|
|
171
|
+
numeric tower.
|
|
172
|
+
|
|
173
|
+
## Scope and limits
|
|
174
|
+
|
|
175
|
+
This project favors definitions that can be read over efficient arithmetic.
|
|
176
|
+
Keep examples small:
|
|
177
|
+
|
|
178
|
+
| Operation | Suggested values |
|
|
179
|
+
| --- | --- |
|
|
180
|
+
| natural-number comparison/addition | 0–10 |
|
|
181
|
+
| natural-number multiplication/division/powers | 0–5 |
|
|
182
|
+
| integer, rational, and polynomial components | absolute values up to 5 |
|
|
183
|
+
| algebraic-root tracing | roughly 12 bisections |
|
|
184
|
+
|
|
185
|
+
`AlgebraicRoot` is deliberately not a complete algebraic-number type. It
|
|
186
|
+
validates one isolated root and shrinks its rational interval, but provides no
|
|
187
|
+
arithmetic between roots and no general mathematical equality.
|
|
188
|
+
|
|
189
|
+
For interval refinement, sign checks use Python's arbitrary-precision integer
|
|
190
|
+
ratios internally. This preserves exactness while avoiding enormous
|
|
191
|
+
intermediate Peano representations; returned endpoints are still `Rational`.
|
|
192
|
+
|
|
193
|
+
## Documentation development
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
make docs # build Japanese at / and English at /en/
|
|
197
|
+
make docs-serve # preview Japanese
|
|
198
|
+
make docs-serve-en # preview English
|
|
199
|
+
make docs-a11y # run WCAG checks on both languages
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The site is deployed from `main` to Cloudflare Workers Static Assets. Deployment
|
|
203
|
+
requires `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` repository secrets.
|
|
204
|
+
|
|
205
|
+
## Release
|
|
206
|
+
|
|
207
|
+
Releases are built by GitHub Actions and published to PyPI with OpenID Connect.
|
|
208
|
+
The `pypi` GitHub environment must be registered as a PyPI Trusted Publisher
|
|
209
|
+
for this repository and `.github/workflows/publish.yml`.
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Public API from Peano arithmetic through algebraic-root approximation."""
|
|
2
|
+
|
|
3
|
+
from .algebraic_root import (
|
|
4
|
+
AlgebraicRoot,
|
|
5
|
+
RationalInterval,
|
|
6
|
+
algebraic_root,
|
|
7
|
+
)
|
|
8
|
+
from .integer import Z_MINUS_ONE, Z_ONE, Z_ZERO, Integer, integer, n2z
|
|
9
|
+
from .natural_number import N_ONE, N_ZERO, NaturalNumber, natural_number, successor
|
|
10
|
+
from .polynomial import (
|
|
11
|
+
P_ONE,
|
|
12
|
+
P_ZERO,
|
|
13
|
+
Polynomial,
|
|
14
|
+
count_real_roots,
|
|
15
|
+
n2p,
|
|
16
|
+
polynomial,
|
|
17
|
+
r2p,
|
|
18
|
+
sign_variations,
|
|
19
|
+
sturm_sequence,
|
|
20
|
+
z2p,
|
|
21
|
+
)
|
|
22
|
+
from .rational import (
|
|
23
|
+
Q_MINUS_ONE,
|
|
24
|
+
Q_ONE,
|
|
25
|
+
Q_ZERO,
|
|
26
|
+
Rational,
|
|
27
|
+
n2r,
|
|
28
|
+
rational,
|
|
29
|
+
z2r,
|
|
30
|
+
)
|
|
31
|
+
from .utils import config_log
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
"NaturalNumber",
|
|
35
|
+
"natural_number",
|
|
36
|
+
"successor",
|
|
37
|
+
"N_ZERO",
|
|
38
|
+
"N_ONE",
|
|
39
|
+
"Integer",
|
|
40
|
+
"integer",
|
|
41
|
+
"n2z",
|
|
42
|
+
"Z_ZERO",
|
|
43
|
+
"Z_ONE",
|
|
44
|
+
"Z_MINUS_ONE",
|
|
45
|
+
"Rational",
|
|
46
|
+
"rational",
|
|
47
|
+
"n2r",
|
|
48
|
+
"z2r",
|
|
49
|
+
"Q_ZERO",
|
|
50
|
+
"Q_ONE",
|
|
51
|
+
"Q_MINUS_ONE",
|
|
52
|
+
"Polynomial",
|
|
53
|
+
"polynomial",
|
|
54
|
+
"n2p",
|
|
55
|
+
"z2p",
|
|
56
|
+
"r2p",
|
|
57
|
+
"P_ZERO",
|
|
58
|
+
"P_ONE",
|
|
59
|
+
"sturm_sequence",
|
|
60
|
+
"sign_variations",
|
|
61
|
+
"count_real_roots",
|
|
62
|
+
"RationalInterval",
|
|
63
|
+
"AlgebraicRoot",
|
|
64
|
+
"algebraic_root",
|
|
65
|
+
"config_log",
|
|
66
|
+
]
|