tritlib 2.1.1__tar.gz → 2.1.2__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.
Files changed (39) hide show
  1. {tritlib-2.1.1 → tritlib-2.1.2}/CHANGELOG.md +11 -4
  2. {tritlib-2.1.1 → tritlib-2.1.2}/PKG-INFO +4 -4
  3. {tritlib-2.1.1 → tritlib-2.1.2}/README.md +2 -2
  4. {tritlib-2.1.1 → tritlib-2.1.2}/pyproject.toml +11 -1
  5. tritlib-2.1.1/.claude/settings.local.json +0 -9
  6. tritlib-2.1.1/CLAUDE.md +0 -79
  7. {tritlib-2.1.1 → tritlib-2.1.2}/.gitignore +0 -0
  8. {tritlib-2.1.1 → tritlib-2.1.2}/LICENSE +0 -0
  9. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/__init__.py +0 -0
  10. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/context.py +0 -0
  11. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/logic/__init__.py +0 -0
  12. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/logic/base.py +0 -0
  13. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/logic/bochvar.py +0 -0
  14. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/logic/heyting.py +0 -0
  15. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/logic/kleene.py +0 -0
  16. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/logic/lukasiewicz.py +0 -0
  17. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/logic/plural.py +0 -0
  18. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/logic/rm3.py +0 -0
  19. {tritlib-2.1.1 → tritlib-2.1.2/src/tritlib}/py.typed +0 -0
  20. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/tfloat.py +0 -0
  21. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/trit.py +0 -0
  22. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/tritarray.py +0 -0
  23. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/trits.py +0 -0
  24. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/trybble.py +0 -0
  25. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/tryte.py +0 -0
  26. {tritlib-2.1.1 → tritlib-2.1.2}/src/tritlib/word.py +0 -0
  27. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_context.py +0 -0
  28. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_logic.py +0 -0
  29. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_logic_kleene.py +0 -0
  30. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_plural.py +0 -0
  31. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_tfloat.py +0 -0
  32. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_tfloat_add.py +0 -0
  33. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_tfloat_div.py +0 -0
  34. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_tfloat_mul.py +0 -0
  35. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_trit.py +0 -0
  36. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_tritarray.py +0 -0
  37. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_trits.py +0 -0
  38. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_tryte.py +0 -0
  39. {tritlib-2.1.1 → tritlib-2.1.2}/tests/test_word.py +0 -0
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [2.1.2] — 2026-11-04
8
+
9
+ ### Fixed
10
+
11
+ - `py.typed` is now shipped in the wheel.
12
+ - The sdist no longer includes local tool configuration
13
+
7
14
  ## [2.1.1] — 2026-07-21
8
15
 
9
16
  ### Fixed
@@ -12,7 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
12
19
  the dividend. 2.1.0 fixed the quotient decision but kept correcting
13
20
  the remainder only after the loop, one unit at a time, against a
14
21
  drift that triples per trit: `divmod(TritArray(-2586565449575, 27),
15
- TritArray(-4, 27))` needed ~10¹² iterations, i.e. never returned.
22
+ TritArray(-4, 27))` needed ~10¹² iterations, i.e. never returned.
16
23
  The result was correct whenever it did return, so the identity
17
24
  `a == b·q + r` kept the bug hidden.
18
25
 
@@ -31,15 +38,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
31
38
 
32
39
  ### Documentation
33
40
 
34
- - `Trits.__divmod__`, `TritArray.__divmod__` and the *Division
35
- pitfalls* section of `CLAUDE.md` described the 2.1.0 state, where the
41
+ - `Trits.__divmod__`, `TritArray.__divmod__` and the _Division
42
+ pitfalls_ section of `CLAUDE.md` described the 2.1.0 state, where the
36
43
  magnitude comparison alone was believed to maintain
37
44
  `|pr| ≤ |d| / 2`. They now document why it does not, and record the
38
45
  even-divisor case as the reason to test small even divisors
39
46
  explicitly: random fuzzing essentially never draws 2, 4 or 6, which
40
47
  is how this survived a full pass.
41
48
  - Documented that an even divisor admits two valid `(quotient,
42
- remainder)` pairs when the remainder reaches exactly `|d| / 2`, and
49
+ remainder)` pairs when the remainder reaches exactly `|d| / 2`, and
43
50
  which one this implementation returns —
44
51
  `divmod(Trits(10), Trits(4))` is `(3, -2)`, not `(2, 2)`.
45
52
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: tritlib
3
- Version: 2.1.1
3
+ Version: 2.1.2
4
4
  Summary: Balanced ternary arithmetic and multi-valued logic library
5
5
  Project-URL: Homepage, https://codeberg.org/setnex-org/tritlib
6
6
  Project-URL: Repository, https://codeberg.org/setnex-org/tritlib
@@ -20,7 +20,7 @@ Requires-Dist: pytest; extra == 'dev'
20
20
  Requires-Dist: pytest-cov; extra == 'dev'
21
21
  Description-Content-Type: text/markdown
22
22
 
23
- # tritlib — v2.0
23
+ # tritlib — v2.1
24
24
 
25
25
  A pure Python library for balanced ternary arithmetic, multi-valued logic, and floating-point representation.
26
26
 
@@ -62,7 +62,7 @@ tritlib provides the building blocks for balanced ternary processor simulation:
62
62
  - Per-trit access (`__getitem__`) and immutable modification (`set`)
63
63
  - Sign extraction and absolute value
64
64
  - Consensus / anti-consensus (trit-level agreement detection)
65
- - Logic system dispatch independent of data types (LMODE selection)
65
+ - Logic system dispatch independent of data types (mirrors the per-instruction logic selector of the Setnex ISA)
66
66
  - Tekum floating-point decode/encode for FPU simulation
67
67
 
68
68
  ## Installation
@@ -1,4 +1,4 @@
1
- # tritlib — v2.0
1
+ # tritlib — v2.1
2
2
 
3
3
  A pure Python library for balanced ternary arithmetic, multi-valued logic, and floating-point representation.
4
4
 
@@ -40,7 +40,7 @@ tritlib provides the building blocks for balanced ternary processor simulation:
40
40
  - Per-trit access (`__getitem__`) and immutable modification (`set`)
41
41
  - Sign extraction and absolute value
42
42
  - Consensus / anti-consensus (trit-level agreement detection)
43
- - Logic system dispatch independent of data types (LMODE selection)
43
+ - Logic system dispatch independent of data types (mirrors the per-instruction logic selector of the Setnex ISA)
44
44
  - Tekum floating-point decode/encode for FPU simulation
45
45
 
46
46
  ## Installation
@@ -2,9 +2,19 @@
2
2
  requires = ["hatchling"]
3
3
  build-backend = "hatchling.build"
4
4
 
5
+ [tool.hatch.build.targets.sdist]
6
+ include = [
7
+ "src/",
8
+ "tests/",
9
+ "CHANGELOG.md",
10
+ "LICENSE",
11
+ "README.md",
12
+ "pyproject.toml",
13
+ ]
14
+
5
15
  [project]
6
16
  name = "tritlib"
7
- version = "2.1.1"
17
+ version = "2.1.2"
8
18
  description = "Balanced ternary arithmetic and multi-valued logic library"
9
19
  readme = "README.md"
10
20
  license = "MIT"
@@ -1,9 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(python -)",
5
- "Bash(timeout 400 /home/newick/Programmes/setnex/tritlib/.venv/bin/python -m pytest test_regressions.py -q -p no:cacheprovider --timeout=60)",
6
- "Bash(timeout 400 /home/newick/Programmes/setnex/tritlib/.venv/bin/python -m pytest test_regressions.py -q -p no:cacheprovider -k \"not full_width and not remainder_is_reduced\")"
7
- ]
8
- }
9
- }
tritlib-2.1.1/CLAUDE.md DELETED
@@ -1,79 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Règle absolue
6
-
7
- **Il t'est interdit de coder.** Tu ne dois jamais modifier la logique d'un fichier `.py` de ce dépôt. La seule modification autorisée dans un fichier `.py` est l'écriture ou la mise à jour de **docstrings**, et uniquement lorsque l'utilisateur le demande explicitement. Toute autre édition de code (ajout/suppression de fonctions, modification d'une expression, refactoring, correction de bug, etc.) est interdite, même si elle semble triviale ou évidente. Lecture, recherche, analyse et explication restent autorisées.
8
-
9
- ## Commands
10
-
11
- Setup and test:
12
- ```bash
13
- python -m venv .venv
14
- source .venv/bin/activate
15
- pip install -e ".[dev]"
16
- python -m pytest # full suite
17
- python -m pytest tests/test_tfloat.py # single file
18
- python -m pytest tests/test_tfloat.py::test_name # single test
19
- python -m pytest --cov=tritlib # with coverage
20
- ```
21
-
22
- Build distribution: `python -m build` (hatchling backend, declared in `pyproject.toml`).
23
-
24
- Python ≥ 3.11 required. No runtime dependencies — only `pytest` and `pytest-cov` for dev.
25
-
26
- ## Architecture
27
-
28
- ### Layering of the core types
29
-
30
- `Trit` → `Trits` → `TritArray` → `TFloat`. Each layer is built on the one below and they must be edited consistent with that direction:
31
-
32
- - **`Trit`** (`trit.py`) — single balanced ternary digit ∈ {N, Z, P}. Provides `half_add`/`full_add` returning `(sum, carry)` where carry is itself a Trit (ternary carry, not binary).
33
- - **`Trits`** (`trits.py`) — arbitrary-precision balanced ternary integer, built as a tuple of `Trit` in **little-endian** order. Division uses the double trial quotient method; result follows symmetric Euclidean semantics (remainder may be negative).
34
- - **`TritArray`** (`tritarray.py`) — fixed-width register-like word at arbitrary width. Three addition modes (`__add__` truncates, `add_with_carry` returns `(result, carry: Trit)`, `add_saturating` clamps). Operations construct via `type(self)._from_trits(trits, width)` (subclass-preserving dispatch) which truncates rather than raising — this is intentional hardware simulation behaviour.
35
- - **`Trybble`** / **`Tryte`** / **`Word`** (`trybble.py`, `tryte.py`, `word.py`) — width-locked subclasses (3 / 9 / 27 trits) aligned with Setnex ISA v0.8. Each declares a `WIDTH` class attribute, an `__init__(self, value)` that forwards to `TritArray.__init__(value, WIDTH)`, and an override of `_from_trits` that ignores any `width` argument and forces `WIDTH`. Arithmetic between same-typed instances preserves the subtype via `type(self)._from_trits`. `to_width(w)` on a subclass returns a base `TritArray` (changing width exits the locked contract).
36
- - **`TFloat`** (`tfloat.py`) — Tekum tapered precision float (arXiv:2512.10964). Stores raw as a `TritArray` (even width ≥ 8, not necessarily 9 or 27). Regime/exponent/fraction/sign are properties derived on demand. Arithmetic (`+`, `*`, `/`) is implemented natively at the trit level via `TritArray` operations (mantissa, double-width products, work-scale bounds), then re-encoded through `_finalize`.
37
-
38
- All types are **immutable**: `__setattr__` raises, `__slots__` enforces fields, and every operation returns a new instance. Do not add mutators.
39
-
40
- Internal storage is **little-endian** (least significant trit first), but string repr and constructor input strings are **big-endian** (`"+-0+"` reads MSB-to-LSB). Watch this direction reversal when editing.
41
-
42
- ### Logic-system dispatch
43
-
44
- The five logic systems live in `src/tritlib/logic/`. Each subclasses `TernaryLogic` (in `base.py`) and only needs to override the operators where it diverges from defaults (most override only `imply_op`).
45
-
46
- `Trit`'s `&`, `|`, `~`, and `imply` look up the active logic via a `ContextVar` (`_current_logic` in `context.py`). When unset, fast inlined Kleene paths are used (no dispatch overhead). The `logic_mode(system)` context manager swaps the active system for the duration of a `with` block. New logic systems should be added by subclassing `TernaryLogic` and exporting from `logic/__init__.py`.
47
-
48
- `pluralize` (in `logic/plural.py`) evaluates a callable across all five systems and reports convergence/divergence — use it when reasoning about whether an expression is logic-system-sensitive.
49
-
50
- ### Tekum format invariants
51
-
52
- When touching `TFloat`:
53
- - Width must be **even and ≥ 8**. Constructors validate this.
54
- - Three special values are stored as the raw `Tryte`: zero (all Z), infinity (all P), NaR (all N). The `_special` slot caches which one. Arithmetic on specials follows **wheel-algebra** semantics (e.g., `x/0 = ∞`, `0/0 = NaR`, `∞/∞ = NaR`) — see `__add__`, `__mul__`, `__truediv__` for the dispatch tables.
55
- - Tekum's defining property: **truncation is rounding**. When reducing precision, slice the anchor; no carry propagation needed. The `_finalize` helper centralises this.
56
- - Cross-width `==` returns `NotImplemented` (no silent coercion).
57
- - `from_float` is the private `_from_float` since 1.3.0; external callers should use the `TFloat(value, width=…)` constructor.
58
-
59
- ### Division pitfalls (Trits / TritArray)
60
-
61
- There is exactly **one** division algorithm, in `Trits.__divmod__`. `TritArray.__divmod__` converts both operands with `to_trits()`, divides there, and packs the results back at the operand width (both always fit, so nothing is truncated). Do not reintroduce a second, fixed-width implementation: the partial remainder reaches `1.5 × |d|` mid-loop, so a `TritArray` comparison at the operand width wraps silently and returns an unreduced remainder — the identity `a == b·q + r` still holds, which is why it hid behind the tests for so long.
62
-
63
- Four things in `Trits.__divmod__` are load-bearing:
64
-
65
- - **The quotient trit is chosen by magnitude**, comparing `V + V` against `±|d|` where `V = 3·pr + t` is the partial remainder scaled by 3 plus the next dividend trit. Deciding on the sign of the leading trit alone (the pre-2.1.0 code) triples the partial remainder at each step — a 52-trit division drifted to `4·10²² × |d|` and never terminated in practice.
66
- - **The quotient is accumulated, not collected**: `q = q·3 ± 1`, never a list of trits appended to. A trit pushed into a list can no longer be revised, and the next point depends on revising it.
67
- - **The remainder is corrected inside the loop, not after it.** One trit cannot always reduce `V`: with `|pr| ≤ |d|/2` the scaled value reaches `1.5·|d| + 1`, while the three possible trits only span `[−1.5·|d|, +1.5·|d|]`. The overshoot is by exactly 1, and it is reachable **for every even divisor** (odd divisors are safe, since `|pr| ≤ (|d|−1)/2` keeps `|V|` in range). The inner loop writes what amounts to a quotient digit of ±2 at that rank; `q + Trits(1)` renormalises it by carrying into the ranks already produced, which balanced ternary addition does for free. It runs at most once per trit. Correcting only at the end still terminates, but one unit at a time against a drift that triples per trit: a 27-trit division by 2 needs ~10¹² iterations, i.e. never. This was the 2.1.1 fix; `2.1.0` shipped the magnitude comparison alone and was still unusable for even divisors.
68
- - **Every trit of the dividend is consumed**, starting from `q = pr = Trits(0)`. Do not "optimise" back either the `partial_rest = s[:len(d)-1]` pre-load or the `if len(self) < len(other): return Trits(0), self` shortcut; the latter returned an unreduced remainder (`34 / 58` gave `(0, 34)` instead of `(1, −24)`), i.e. a second remainder convention inside the same function.
69
-
70
- Remainder semantics are symmetric/balanced: `|r| ≤ |b|/2`, so the remainder takes whichever sign minimises its magnitude — **not** the sign of the dividend (`divmod(Trits(-200), Trits(-57)) == (Trits(4), Trits(28))`). For an even divisor the remainder can hit exactly `|b|/2`, where two `(q, r)` pairs satisfy the contract; the loop's own choice is what ships (`divmod(Trits(10), Trits(4)) == (Trits(3), Trits(-2))`). Do not freeze the other one in a test.
71
-
72
- Any test touching division must assert `2·|r| ≤ |b|` alongside `b·q + r == a`. The identity alone passes even when the algorithm is broken — it held throughout both the 2.1.0 and 2.1.1 bugs. Test small **even** divisors explicitly, at full width: random divisors essentially never hit 2, 4 or 6, which is how the even-divisor case survived a full fuzzing pass.
73
-
74
- ## Conventions to follow
75
-
76
- - Type-hinted, immutable, dunder-rich public API. Add `__hash__`, `__eq__`, and `@total_ordering` where comparable; raise `AttributeError` from `__setattr__`.
77
- - Operators returning `NotImplemented` (not raising) for unsupported operand types — except `__divmod__`, which raises `TypeError` to match Python's `divmod` protocol.
78
- - New public symbols must be re-exported from the appropriate `__init__.py` and added to `__all__`.
79
- - Docstrings on public classes and methods; the project ships `py.typed` for downstream mypy users.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes