rerum 0.2.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.
- rerum-0.2.2/.github/workflows/ci.yml +54 -0
- rerum-0.2.2/.github/workflows/docs.yml +50 -0
- rerum-0.2.2/.github/workflows/publish.yml +55 -0
- rerum-0.2.2/.gitignore +56 -0
- rerum-0.2.2/CLAUDE.md +80 -0
- rerum-0.2.2/PKG-INFO +567 -0
- rerum-0.2.2/README.md +532 -0
- rerum-0.2.2/docs/api-reference.md +223 -0
- rerum-0.2.2/docs/cli.md +198 -0
- rerum-0.2.2/docs/dsl-reference.md +138 -0
- rerum-0.2.2/docs/examples.md +208 -0
- rerum-0.2.2/docs/getting-started.md +152 -0
- rerum-0.2.2/docs/index.md +54 -0
- rerum-0.2.2/examples/algebra.rules +39 -0
- rerum-0.2.2/examples/calculus.rules +41 -0
- rerum-0.2.2/examples/custom_prelude.py +61 -0
- rerum-0.2.2/examples/demo.py +279 -0
- rerum-0.2.2/examples/demo.rerum +20 -0
- rerum-0.2.2/examples/number_theory.rules +31 -0
- rerum-0.2.2/mkdocs.yml +51 -0
- rerum-0.2.2/pyproject.toml +80 -0
- rerum-0.2.2/rerum/__init__.py +137 -0
- rerum-0.2.2/rerum/cli.py +722 -0
- rerum-0.2.2/rerum/engine.py +1622 -0
- rerum-0.2.2/rerum/rewriter.py +957 -0
- rerum-0.2.2/rerum/tests/__init__.py +1 -0
- rerum-0.2.2/rerum/tests/test_bindings.py +216 -0
- rerum-0.2.2/rerum/tests/test_cli.py +368 -0
- rerum-0.2.2/rerum/tests/test_engine_methods.py +449 -0
- rerum-0.2.2/rerum/tests/test_expr_builder.py +120 -0
- rerum-0.2.2/rerum/tests/test_groups.py +420 -0
- rerum-0.2.2/rerum/tests/test_guards.py +321 -0
- rerum-0.2.2/rerum/tests/test_includes.py +252 -0
- rerum-0.2.2/rerum/tests/test_priorities.py +228 -0
- rerum-0.2.2/rerum/tests/test_rewriter.py +303 -0
- rerum-0.2.2/rerum/tests/test_sequencing.py +181 -0
- rerum-0.2.2/rerum/tests/test_strategies.py +260 -0
- rerum-0.2.2/rerum/tests/test_trace.py +285 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ matrix.python-version }}
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: |
|
|
27
|
+
python -m pip install --upgrade pip
|
|
28
|
+
pip install -e ".[dev]"
|
|
29
|
+
|
|
30
|
+
- name: Run tests with coverage
|
|
31
|
+
run: |
|
|
32
|
+
pytest --cov=rerum --cov-report=xml --cov-report=term-missing
|
|
33
|
+
|
|
34
|
+
- name: Upload coverage to Codecov
|
|
35
|
+
if: matrix.python-version == '3.12'
|
|
36
|
+
uses: codecov/codecov-action@v4
|
|
37
|
+
with:
|
|
38
|
+
files: ./coverage.xml
|
|
39
|
+
fail_ci_if_error: false
|
|
40
|
+
|
|
41
|
+
lint:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
|
|
46
|
+
- name: Set up Python
|
|
47
|
+
uses: actions/setup-python@v5
|
|
48
|
+
with:
|
|
49
|
+
python-version: "3.12"
|
|
50
|
+
|
|
51
|
+
- name: Check build
|
|
52
|
+
run: |
|
|
53
|
+
pip install build
|
|
54
|
+
python -m build
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Deploy Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
pages: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: "pages"
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: '3.12'
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: |
|
|
31
|
+
pip install mkdocs mkdocs-material
|
|
32
|
+
|
|
33
|
+
- name: Build docs
|
|
34
|
+
run: mkdocs build
|
|
35
|
+
|
|
36
|
+
- name: Upload artifact
|
|
37
|
+
uses: actions/upload-pages-artifact@v3
|
|
38
|
+
with:
|
|
39
|
+
path: site
|
|
40
|
+
|
|
41
|
+
deploy:
|
|
42
|
+
environment:
|
|
43
|
+
name: github-pages
|
|
44
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
needs: build
|
|
47
|
+
steps:
|
|
48
|
+
- name: Deploy to GitHub Pages
|
|
49
|
+
id: deployment
|
|
50
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write # Required for trusted publishing
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Python
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install build dependencies
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
pip install build
|
|
25
|
+
|
|
26
|
+
- name: Build package
|
|
27
|
+
run: python -m build
|
|
28
|
+
|
|
29
|
+
- name: Upload build artifacts
|
|
30
|
+
uses: actions/upload-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/
|
|
34
|
+
|
|
35
|
+
publish-pypi:
|
|
36
|
+
needs: build
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
environment:
|
|
39
|
+
name: pypi
|
|
40
|
+
url: https://pypi.org/project/rerum/
|
|
41
|
+
|
|
42
|
+
steps:
|
|
43
|
+
- name: Download build artifacts
|
|
44
|
+
uses: actions/download-artifact@v4
|
|
45
|
+
with:
|
|
46
|
+
name: dist
|
|
47
|
+
path: dist/
|
|
48
|
+
|
|
49
|
+
- name: Publish to PyPI
|
|
50
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
51
|
+
with:
|
|
52
|
+
# Uses trusted publishing if configured, otherwise falls back to API token
|
|
53
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
54
|
+
# For trusted publishing, configure at:
|
|
55
|
+
# https://pypi.org/manage/account/publishing/
|
rerum-0.2.2/.gitignore
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
.env
|
|
25
|
+
.venv
|
|
26
|
+
env/
|
|
27
|
+
venv/
|
|
28
|
+
ENV/
|
|
29
|
+
|
|
30
|
+
# Testing
|
|
31
|
+
.pytest_cache/
|
|
32
|
+
.coverage
|
|
33
|
+
htmlcov/
|
|
34
|
+
.tox/
|
|
35
|
+
.nox/
|
|
36
|
+
coverage.xml
|
|
37
|
+
*.cover
|
|
38
|
+
*.py,cover
|
|
39
|
+
.hypothesis/
|
|
40
|
+
|
|
41
|
+
# IDE
|
|
42
|
+
.idea/
|
|
43
|
+
.vscode/
|
|
44
|
+
*.swp
|
|
45
|
+
*.swo
|
|
46
|
+
*~
|
|
47
|
+
|
|
48
|
+
# OS
|
|
49
|
+
.DS_Store
|
|
50
|
+
Thumbs.db
|
|
51
|
+
|
|
52
|
+
# Project specific
|
|
53
|
+
.benchmarks/
|
|
54
|
+
|
|
55
|
+
# MkDocs
|
|
56
|
+
site/
|
rerum-0.2.2/CLAUDE.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
RERUM (Rewriting Expressions via Rules Using Morphisms) is a pattern matching and term rewriting library for symbolic computation in Python. It provides a DSL for defining rewrite rules and applies them to s-expression-style nested lists.
|
|
8
|
+
|
|
9
|
+
## Build and Test Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install -e ".[dev]" # Install with dev dependencies
|
|
13
|
+
pip install -e ".[docs]" # Install with docs dependencies
|
|
14
|
+
pytest # Run all tests
|
|
15
|
+
pytest --cov=rerum --cov-report=term-missing # With coverage
|
|
16
|
+
pytest rerum/tests/test_guards.py -v # Single test file
|
|
17
|
+
pytest rerum/tests/test_guards.py::TestGuardParsing::test_parse_when_clause -v # Single test
|
|
18
|
+
mkdocs serve # Local docs server
|
|
19
|
+
mkdocs build # Build docs to site/
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Architecture
|
|
23
|
+
|
|
24
|
+
### Core Modules
|
|
25
|
+
|
|
26
|
+
**rewriter.py** - Low-level pattern matching engine
|
|
27
|
+
- `match(pattern, expr, bindings)` - Pattern matching with binding extraction
|
|
28
|
+
- `instantiate(skeleton, bindings, fold_funcs)` - Skeleton instantiation with `(! ...)` compute evaluation
|
|
29
|
+
- `rewriter(rules, fold_funcs)` - Factory that creates a simplifier function
|
|
30
|
+
- Preludes: `ARITHMETIC_PRELUDE`, `MATH_PRELUDE`, `PREDICATE_PRELUDE`, `FULL_PRELUDE`
|
|
31
|
+
|
|
32
|
+
**engine.py** - High-level DSL and rule engine
|
|
33
|
+
- `RuleEngine` - Main API: load rules, apply strategies, manage groups
|
|
34
|
+
- `RuleMetadata` - Rule name, description, priority, condition (guard)
|
|
35
|
+
- `RewriteTrace` / `RewriteStep` - Tracing infrastructure
|
|
36
|
+
- `parse_sexpr()` / `format_sexpr()` - S-expression I/O
|
|
37
|
+
- `E` - Expression builder singleton
|
|
38
|
+
|
|
39
|
+
**cli.py** - Command-line interface
|
|
40
|
+
- `RerumREPL` - Interactive REPL with readline support
|
|
41
|
+
- `ScriptRunner` - Executes `.rerum` scripts
|
|
42
|
+
- Supports pipe mode, expression mode, custom prelude loading
|
|
43
|
+
|
|
44
|
+
### Key Design Patterns
|
|
45
|
+
|
|
46
|
+
- **Rules vs Preludes**: Rules are pure data (DSL/JSON serializable); preludes are Python code defining what `(! op ...)` operations do. Security boundary: rules can only invoke prelude-enabled operations.
|
|
47
|
+
- **Fluent API**: Methods return `self` for chaining: `.with_prelude()`, `.load_dsl()`, `.disable_group()`
|
|
48
|
+
- **Bindings**: `Bindings` class wraps raw bindings with dict-like access; `NoMatch` singleton is falsy
|
|
49
|
+
- **Strategies**: exhaustive (default), once, bottomup, topdown - control rule application order
|
|
50
|
+
|
|
51
|
+
### DSL Features
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
@name: (pattern) => (skeleton) # Basic rule
|
|
55
|
+
@name[100]: (pattern) => (skeleton) # With priority (higher fires first)
|
|
56
|
+
@name: (pattern) => (skeleton) when (condition) # With guard
|
|
57
|
+
[groupname] # Start a named group
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Pattern syntax: `?x`, `?x:const`, `?x:var`, `?x:free(v)`, `?x...`
|
|
61
|
+
Skeleton syntax: `:x`, `:x...`, `(! op args...)`
|
|
62
|
+
|
|
63
|
+
### Expression Representation
|
|
64
|
+
|
|
65
|
+
Expressions are nested Python lists in prefix notation:
|
|
66
|
+
```python
|
|
67
|
+
["+", "x", ["*", 2, "y"]] # represents: x + 2*y
|
|
68
|
+
```
|
|
69
|
+
Atoms are strings (variables) or numbers (constants).
|
|
70
|
+
|
|
71
|
+
## CLI Usage
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
rerum # Start REPL
|
|
75
|
+
rerum script.rerum # Run script
|
|
76
|
+
rerum -r rules.rules -p full -e "(+ x 0)" # One-shot evaluation
|
|
77
|
+
echo "(+ x 0)" | rerum -r rules.rules -q # Pipe mode
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
REPL commands: `:help`, `:load FILE`, `:rules`, `:clear`, `:prelude NAME`, `:trace on/off`, `:strategy NAME`, `:groups`, `:enable GROUP`, `:disable GROUP`, `:quit`
|