Compare commits
2 Commits
88ee579114
...
3f8a4a5bf0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f8a4a5bf0 | ||
|
|
1df893c8f3 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
venv
|
venv
|
||||||
instance
|
instance
|
||||||
__pycache__
|
__pycache__
|
||||||
|
found.pi
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ Mathy is a playground for experimenting with streamed arithmetic on very large i
|
|||||||
## What's Here
|
## What's Here
|
||||||
- `mathstream/` – Streaming big-int helpers (`StreamNumber`, arithmetic primitives, garbage collection utilities). See `mathstream/README.md` for an in-depth guide.
|
- `mathstream/` – Streaming big-int helpers (`StreamNumber`, arithmetic primitives, garbage collection utilities). See `mathstream/README.md` for an in-depth guide.
|
||||||
- `collatz_ui/` + `collatz.py` – A curses dashboard that visualizes Collatz walks. The UI pushes work onto a background thread so the main loop can keep the interface responsive while mathstream evaluates each step.
|
- `collatz_ui/` + `collatz.py` – A curses dashboard that visualizes Collatz walks. The UI pushes work onto a background thread so the main loop can keep the interface responsive while mathstream evaluates each step.
|
||||||
|
- `pi_finder/` + `find_my.py` – Nilakantha-based π explorer with both CLI output and a curses dashboard powered by mathstream primitives.
|
||||||
- `stupid.py` – Experimental Collatz-based encoder/decoder that maps ASCII message chunks to Collatz seeds and replays the sequence to recover the text.
|
- `stupid.py` – Experimental Collatz-based encoder/decoder that maps ASCII message chunks to Collatz seeds and replays the sequence to recover the text.
|
||||||
- `seed_start.py` – Utility for seeding `start.txt` with huge streamed additions sourced from randomness or deterministic sequences.
|
- `seed_start.py` – Utility for seeding `start.txt` with huge streamed additions sourced from randomness or deterministic sequences.
|
||||||
- `tests/` – Sample digit files used by the regression script in `test.py`.
|
- `tests/` – Sample digit files used by the regression script in `test.py`.
|
||||||
@ -19,13 +20,15 @@ pip install -e .
|
|||||||
From there you can explore the components:
|
From there you can explore the components:
|
||||||
- Run the regression checks: `python test.py`
|
- Run the regression checks: `python test.py`
|
||||||
- Launch the Collatz dashboard: `python collatz.py`
|
- Launch the Collatz dashboard: `python collatz.py`
|
||||||
|
- Stream π digits to the terminal: `python find_my.py --ui`
|
||||||
|
- Print a quick π approximation: `python find_my.py --digits 200`
|
||||||
- Try the Collatz encoder prototype: `python stupid.py`
|
- Try the Collatz encoder prototype: `python stupid.py`
|
||||||
- Seed the running total file: `python seed_start.py --seed 100 --mode seq`
|
- Seed the running total file: `python seed_start.py --seed 100 --mode seq`
|
||||||
|
|
||||||
All streamed results land in `instance/log/`. If you need a clean slate, call `mathstream.clear_logs()` or delete that directory between runs.
|
All streamed results land in `instance/log/`. If you need a clean slate, call `mathstream.clear_logs()` or delete that directory between runs.
|
||||||
|
|
||||||
## Experiments and Next Steps
|
## Experiments and Next Steps
|
||||||
- **Streaming worker** – The Collatz UI's worker thread (`collatz_ui/app.py`) demonstrates how to keep long-running streamed computations off the main event loop.
|
- **Streaming workers** – The Collatz and π dashboards (`collatz_ui/app.py`, `pi_finder/ui/app.py`) showcase background threads feeding long-running computations into a curses UI.
|
||||||
- **Collatz encoding** – `stupid.py` currently encodes a message by turning ASCII blocks into integers and treating the first block as the Collatz seed. Extending this to use the full sequence (or to target specific steps) is an open avenue for exploration.
|
- **Collatz encoding** – `stupid.py` currently encodes a message by turning ASCII blocks into integers and treating the first block as the Collatz seed. Extending this to use the full sequence (or to target specific steps) is an open avenue for exploration.
|
||||||
- **More tests** – `test.py` covers the primary mathstream operations. Add pytest cases or property tests under `tests/` as new behaviours land.
|
- **More tests** – `test.py` covers the primary mathstream operations. Add pytest cases or property tests under `tests/` as new behaviours land.
|
||||||
|
|
||||||
|
|||||||
2
WORK.md
2
WORK.md
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Figured I’d write down how the whole thing is wired, more like a brain dump than polished docs. If you’re diving in to fix something, this should save you a bunch of spelunking.
|
Figured I’d write down how the whole thing is wired, more like a brain dump than polished docs. If you’re diving in to fix something, this should save you a bunch of spelunking.
|
||||||
|
|
||||||
> New top-level `README.md` now mirrors the high-level pitch, cross-links experiments (`collatz_ui`, `stupid.py`, `seed_start.py`), and lists quick-start commands (`pip install -e .`, `python test.py`, etc.). Treat this file as the deep dive into the mathstream core.
|
> New top-level `README.md` now mirrors the high-level pitch, cross-links experiments (`collatz_ui`, `pi_finder`, `find_my.py`, `stupid.py`, `seed_start.py`), and lists quick-start commands (`pip install -e .`, `python test.py`, etc.). Treat this file as the deep dive into the mathstream core.
|
||||||
|
|
||||||
## Directory map (so you know where to poke)
|
## Directory map (so you know where to poke)
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,7 @@ Each arithmetic call writes its result back into `instance/log` (configurable vi
|
|||||||
- **Sign-aware** – Addition, subtraction, multiplication, division (`//` behavior), modulo, and exponentiation (non-negative exponents) all respect operand sign. Division/modulo follow Python’s floor-division rules.
|
- **Sign-aware** – Addition, subtraction, multiplication, division (`//` behavior), modulo, and exponentiation (non-negative exponents) all respect operand sign. Division/modulo follow Python’s floor-division rules.
|
||||||
- **Utilities** – `clear_logs()` wipes prior staged results so you can start fresh.
|
- **Utilities** – `clear_logs()` wipes prior staged results so you can start fresh.
|
||||||
- **Manual freeing** – Call `stream.free()` (or `free_stream(stream)`) once you are done with a staged number to release its reference immediately. Logger metadata keeps per-path reference counts so the final free removes the backing file on the spot.
|
- **Manual freeing** – Call `stream.free()` (or `free_stream(stream)`) once you are done with a staged number to release its reference immediately. Logger metadata keeps per-path reference counts so the final free removes the backing file on the spot.
|
||||||
|
- **GC toggle** – Need total control over when files disappear? Flip `mathstream.set_manual_free_only(True)` so automatic finalizers stop unlinking staged files; they will persist until you call `free()` (or `collect_garbage`). Use `mathstream.manual_free_only_enabled()` to inspect the current setting.
|
||||||
- **Parity helpers** – `is_even` and `is_odd` inspect the streamed digits without materializing the integer.
|
- **Parity helpers** – `is_even` and `is_odd` inspect the streamed digits without materializing the integer.
|
||||||
- **Garbage collection** – `collect_garbage(score_threshold)` computes a score from file age, access count, and reference count (tracked in `instance/mathstream_logs.sqlite`, freshly truncated each run). Files whose score meets or exceeds the threshold are deleted, letting you tune how aggressively to reclaim space. Both staged results and literal caches participate. Use `tracked_files()` or `active_streams()` to inspect current state.
|
- **Garbage collection** – `collect_garbage(score_threshold)` computes a score from file age, access count, and reference count (tracked in `instance/mathstream_logs.sqlite`, freshly truncated each run). Files whose score meets or exceeds the threshold are deleted, letting you tune how aggressively to reclaim space. Both staged results and literal caches participate. Use `tracked_files()` or `active_streams()` to inspect current state.
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,12 @@
|
|||||||
from .engine import clear_logs, add, sub, mul, div, mod, pow, is_even, is_odd
|
from .engine import clear_logs, add, sub, mul, div, mod, pow, is_even, is_odd
|
||||||
from .exceptions import MathStreamError, DivideByZeroError
|
from .exceptions import MathStreamError, DivideByZeroError
|
||||||
from .number import StreamNumber, free_stream, active_streams
|
from .number import (
|
||||||
|
StreamNumber,
|
||||||
|
free_stream,
|
||||||
|
active_streams,
|
||||||
|
set_manual_free_only,
|
||||||
|
manual_free_only_enabled,
|
||||||
|
)
|
||||||
from .utils import collect_garbage, tracked_files
|
from .utils import collect_garbage, tracked_files
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@ -18,6 +24,8 @@ __all__ = [
|
|||||||
"StreamNumber",
|
"StreamNumber",
|
||||||
"free_stream",
|
"free_stream",
|
||||||
"active_streams",
|
"active_streams",
|
||||||
|
"set_manual_free_only",
|
||||||
|
"manual_free_only_enabled",
|
||||||
"MathStreamError",
|
"MathStreamError",
|
||||||
"DivideByZeroError",
|
"DivideByZeroError",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -12,6 +12,7 @@ from .utils import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
LOG_DIR = Path("./instance/log")
|
LOG_DIR = Path("./instance/log")
|
||||||
|
_MANUAL_FREE_ONLY = False
|
||||||
|
|
||||||
|
|
||||||
def _ensure_log_dir() -> None:
|
def _ensure_log_dir() -> None:
|
||||||
@ -138,6 +139,8 @@ def _decrement_active(path: Path, delete_file: bool = True) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def _finalize_instance(path_str: str) -> None:
|
def _finalize_instance(path_str: str) -> None:
|
||||||
|
if _MANUAL_FREE_ONLY:
|
||||||
|
return
|
||||||
_decrement_active(Path(path_str))
|
_decrement_active(Path(path_str))
|
||||||
|
|
||||||
|
|
||||||
@ -149,3 +152,14 @@ def free_stream(number: StreamNumber, *, delete_file: bool = True) -> None:
|
|||||||
def active_streams() -> Dict[str, int]:
|
def active_streams() -> Dict[str, int]:
|
||||||
"""Return the active StreamNumber paths mapped to in-memory reference counts."""
|
"""Return the active StreamNumber paths mapped to in-memory reference counts."""
|
||||||
return dict(_ACTIVE_COUNTER)
|
return dict(_ACTIVE_COUNTER)
|
||||||
|
|
||||||
|
|
||||||
|
def set_manual_free_only(enabled: bool) -> None:
|
||||||
|
"""Toggle whether garbage collection happens only via explicit .free() calls."""
|
||||||
|
global _MANUAL_FREE_ONLY
|
||||||
|
_MANUAL_FREE_ONLY = bool(enabled)
|
||||||
|
|
||||||
|
|
||||||
|
def manual_free_only_enabled() -> bool:
|
||||||
|
"""Return the current manual-free-only toggle."""
|
||||||
|
return _MANUAL_FREE_ONLY
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user