A small, resume-able producer/consumer pipeline that generates Euclid numbers (E = primorial + 1), marks probable primes (via Miller–Rabin), and records results in a SQLite database for later inspection and processing. Designed for long-running computations and sharing results (for example via Zenodo).
This repository contains two main components:
producer.py— incrementally computes primorials and Euclid numbers, runs Miller–Rabin, and writes records to a SQLite database (euclid.db). It is resume-able: if stopped and restarted it continues from the last processed index.consumer.py— picks upcandidaterecords from the DB and runs stronger trial division / Pollard–Rho (or other factorization methods) to find nontrivial factors and classify records.
- Resume-able storage using a single SQLite file (
euclid.db). - Each
euclidrow recordslast_prime(the last prime used in the primorial), the Euclid number (stored as text), bit-length, MR result, small factors (if any), and status (candidate/composite/prime/done). - Split producer/consumer architecture so you can run the expensive primality tests and factorization in separate processes or machines.
- Simple CLI options for tuning Miller–Rabin rounds, trial division limits, and batch sizes.
- Python 3.8+ (uses standard library for the default code)
- Optional:
pandasfor CSV/Excel export - Optional:
pyecmor other factorization libraries for improved factoring in the consumer
Example (optional dependencies):
python3 -m venv .venv
source .venv/bin/activate
pip install pandas pyecm-
Put
producer.pyandconsumer.pyin a directory, e.g.~/euclid. -
Run the producer in one terminal (this will create
euclid.dbthe first time):
python3 producer.py --db euclid.db --mr 12 --trial 200000--mrsets Miller–Rabin rounds (higher → lower false-prime probability).--trialsets a small-factor trial-division limit used by the producer to catch tiny factors quickly.
- In a separate terminal (or machine) run the consumer:
python3 consumer.py --db euclid.db --trial 1000000The consumer will fetch status='candidate' rows and try to factor them. Found factors will be written to the DB and the status updated.
primes (optional)
idxINTEGER PRIMARY KEYpINTEGER
euclid
idxINTEGER PRIMARY KEY — indexn(number of primes multiplied)last_primeINTEGER — the last prime used in the primorial (e.g. 29)primorialTEXT (optional) — decimal string of the primorial (may be large)euclidTEXT — primorial + 1 as decimal stringbitsINTEGER — bit-length ofeuclidis_probable_primeINTEGER — Miller–Rabin result (0/1 or NULL if not tested)small_factorTEXT — comma-separated small factors if foundstatusTEXT —candidate/done/composite/primemr_roundsINTEGER — MR rounds used when testingcreated_at,updated_atTEXT — ISO timestamps
If your DB was created before
last_primeexisted, add the column with:ALTER TABLE euclid ADD COLUMN last_prime INTEGER;
Open the DB with the sqlite3 CLI, DB Browser, or VS Code extension. Useful queries:
- Show last 10 rows:
SELECT idx, last_prime, bits, is_probable_prime, small_factor, status
FROM euclid
ORDER BY idx DESC LIMIT 10;- List current candidates (probable primes):
SELECT idx, last_prime, bits, euclid
FROM euclid
WHERE status='candidate'
ORDER BY idx;- Find rows with discovered factors:
SELECT idx, last_prime, small_factor
FROM euclid
WHERE small_factor IS NOT NULL
ORDER BY idx;- How many rows total:
SELECT COUNT(*) FROM euclid;Run sqlite3 -header -column euclid.db for more readable CLI output.
- DB Browser for SQLite —
sudo apt install sqlitebrowserand thensqlitebrowser euclid.db. - DBeaver —
snap install dbeaver-ceand connect to the file. - VS Code — use a SQLite extension (e.g.
SQLiteby Alex Covizzi) and open the DB file inside the editor. - Export to CSV using Python & pandas:
import sqlite3
import pandas as pd
conn = sqlite3.connect('euclid.db')
df = pd.read_sql_query('SELECT * FROM euclid', conn)
df.to_csv('euclid.csv', index=False)Simple workflow using tmux:
tmux
python3 producer.py --db euclid.db
# detach with Ctrl+b dExample systemd unit for the producer (/etc/systemd/system/euclid-producer.service):
[Unit]
Description=Euclid Producer
After=network.target
[Service]
User=YOUR_USER
WorkingDirectory=/home/YOUR_USER/euclid
ExecStart=/usr/bin/python3 /home/YOUR_USER/euclid/producer.py --db /home/YOUR_USER/euclid/euclid.db --mr 12
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now euclid-producer.serviceNote: adjust paths and user to match your environment.
primorialgrows very fast — storing the primorial and euclid as decimalTEXTis simple and portable but the file size will grow if you keep many large values.- Miller–Rabin: if MR returns
compositethe result is certain. If it returnsprobable prime, there is a small probability of error. Increase MR rounds to reduce this risk or use a provable algorithm such as ECPP for a certificate. - Consumer: consider adding ECM (
pyecm) or other specialized factorization tools for better results on medium-size factors. - If multiple processes write concurrently, use SQLite WAL mode to reduce
database is lockederrors:
PRAGMA journal_mode = WAL;Contributions welcome. Suggested improvements:
- Add optional ECPP integration (produce/verify primality certificates).
- Replace Python big-int primorial computations with GMP-backed code for extreme-scale runs.
- Add more robust job-queueing (e.g. Redis/RQ or Celery) if you want distributed workers.
Please open issues / PRs in the repository.
This project is available under the MIT License. See LICENSE.