161 lines
5.9 KiB
Markdown
161 lines
5.9 KiB
Markdown
# Contributing to SymClaw
|
|
|
|
Thank you for your interest in SymClaw! This guide will help you get started.
|
|
|
|
## Development Environment
|
|
|
|
### Nix (Recommended)
|
|
|
|
```bash
|
|
git clone https://github.com/symclaw/symclaw.git
|
|
cd symclaw
|
|
nix develop # Drops you into a shell with Rust, wasm-pack, and all tools
|
|
cargo test # Verify everything works
|
|
```
|
|
|
|
### Manual Setup
|
|
|
|
Requirements:
|
|
- Rust 1.93.0+ (edition 2024)
|
|
- wasm-pack (for WASM builds)
|
|
- cargo-nextest (recommended for faster test runs)
|
|
|
|
```bash
|
|
git clone https://github.com/symclaw/symclaw.git
|
|
cd symclaw
|
|
rustup toolchain install stable
|
|
cargo test
|
|
```
|
|
|
|
## Code Style
|
|
|
|
- **Format**: `cargo fmt` — all code must pass `cargo fmt --check`
|
|
- **Lint**: `cargo clippy` — zero warnings policy (pedantic + nursery enabled)
|
|
- **No unsafe**: `unsafe` code is denied workspace-wide
|
|
- **File limit**: Keep files under 1,250 lines. If a module grows past this, split it.
|
|
- **Documentation**: All public items should have doc comments (`missing_docs` is warned)
|
|
- **Error handling**: Use `thiserror` for library errors, `anyhow` for binary crates. No `.unwrap()` or `.expect()` (clippy-denied).
|
|
|
|
## Testing
|
|
|
|
All PRs must pass the full test suite:
|
|
|
|
```bash
|
|
# Run all tests
|
|
cargo test --workspace
|
|
|
|
# Run property-based tests (proptest)
|
|
cargo test --workspace -- --include-ignored proptest
|
|
|
|
# Run with nextest for parallel execution
|
|
cargo nextest run --workspace
|
|
```
|
|
|
|
### Test Requirements
|
|
|
|
- **Unit tests**: Every public function needs at least one test
|
|
- **Property tests**: Mathematical operations must have proptest coverage verifying algebraic identities (e.g., `simplify(simplify(x)) == simplify(x)`, `d/dx(integral(f, x)) == f`)
|
|
- **Edge cases**: Test with zero, negative numbers, large coefficients, deeply nested expressions
|
|
- **No flaky tests**: Tests must be deterministic. If randomized, use a fixed seed.
|
|
|
|
Current test count: **426 tests** — PRs should not reduce this number.
|
|
|
|
## Pull Request Process
|
|
|
|
1. **Fork** the repository and create a branch from `main`
|
|
2. **Branch naming**: `feat/description`, `fix/description`, or `refactor/description`
|
|
3. **Make your changes** with tests
|
|
4. **Run the full check suite**:
|
|
```bash
|
|
cargo fmt --check
|
|
cargo clippy --workspace -- -D warnings
|
|
cargo test --workspace
|
|
```
|
|
5. **Open a PR** with a clear description of what and why
|
|
6. **CI must pass** — GitHub Actions runs tests on Linux, macOS, Windows, and WASM
|
|
7. **One approval** required from a maintainer
|
|
|
|
### Commit Messages
|
|
|
|
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
|
|
```
|
|
feat(simplify): add trig identity sin²+cos²=1
|
|
fix(parser): handle implicit multiplication with parentheses
|
|
docs: update API reference for taylor function
|
|
test(integrate): add proptest for by-parts rule
|
|
```
|
|
|
|
## Adding Rewrite Rules
|
|
|
|
Rewrite rules are the heart of SymClaw's simplification engine. Adding new rules requires extra rigor:
|
|
|
|
1. **Correctness proof sketch**: In your PR description, provide a brief mathematical proof or reference that the rewrite is always valid
|
|
2. **Proptest coverage**: Add a property test that generates random expressions and verifies the rule preserves equality (via numeric evaluation)
|
|
3. **Benchmark**: Run `cargo bench` before and after. Rules that cause >5% regression in saturation time need justification
|
|
4. **E-graph tests**: Add a test in `egraph/` showing the rule fires and produces the expected extraction
|
|
|
|
Example PR description for a new rule:
|
|
```
|
|
## New rule: `ln(a*b) → ln(a) + ln(b)` (for a > 0, b > 0)
|
|
|
|
**Proof**: Direct consequence of logarithm properties.
|
|
Restriction to positive reals avoids complex branch issues.
|
|
|
|
**Proptest**: Generates random positive a, b ∈ (0.01, 1000),
|
|
verifies |ln(a*b) - (ln(a) + ln(b))| < 1e-10.
|
|
|
|
**Benchmark**: No measurable change in saturation time (30 rules → 31).
|
|
```
|
|
|
|
## Good First Issues
|
|
|
|
Looking for a place to start? These are great entry points:
|
|
|
|
- **Add missing trig identities** — e.g., double-angle formulas as rewrite rules
|
|
- **Improve LaTeX rendering** — Better spacing for specific expression patterns
|
|
- **CLI quality-of-life** — Tab completion for function names
|
|
- **More integration patterns** — `∫ sec(x) dx`, `∫ csc(x) dx`
|
|
- **WASM examples** — A simple web page demonstrating the WASM API
|
|
- **Documentation** — Examples, tutorials, fixing typos
|
|
- **Error messages** — Make parser errors more user-friendly with span information
|
|
|
|
Check the [issue tracker](https://github.com/symclaw/symclaw/issues?q=label%3A%22good+first+issue%22) for labeled issues.
|
|
|
|
## Architecture Overview for New Contributors
|
|
|
|
```
|
|
symclaw-core (the engine — start here)
|
|
├── ast.rs # Expression tree: Arc<Expr> with Symbol interning
|
|
├── parser.rs # nom-based parser: string → Arc<Expr>
|
|
├── simplify.rs # Multi-pass simplification pipeline
|
|
├── egraph.rs # E-graph equality saturation (egg crate)
|
|
├── differentiate.rs# Symbolic differentiation
|
|
├── integrate.rs # Symbolic integration
|
|
├── solve.rs # Equation solver
|
|
├── series.rs # Taylor/Maclaurin expansion
|
|
├── eval.rs # Numeric evaluation (f64)
|
|
├── latex.rs # LaTeX rendering
|
|
└── interner.rs # String interning for symbols
|
|
```
|
|
|
|
**Key design decisions:**
|
|
- Expressions are `Arc<Expr>` — immutable, cheaply cloneable, shared subtrees
|
|
- Symbols are interned integers, not strings — fast comparison
|
|
- Simplification runs before other operations — canonical form matters
|
|
- E-graph is opt-in (used for deep simplification, not every operation)
|
|
|
|
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full deep dive.
|
|
|
|
## Code of Conduct
|
|
|
|
This project follows the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct). Be kind, be constructive, be welcoming.
|
|
|
|
## Questions?
|
|
|
|
- Open a [Discussion](https://github.com/symclaw/symclaw/discussions) on GitHub
|
|
- Join our [Discord](https://discord.gg/symclaw)
|
|
- Email: omar@symclaw.dev
|
|
|
|
Thank you for helping make symbolic computing accessible to everyone! 🦀
|