clifford-codegen 0.3.0

Code generator for optimized geometric algebra types
Documentation
# clifford-codegen

Code generator for optimized geometric algebra types from algebra specifications.

## Workflow Overview

Generating a new algebra involves three steps:

1. **Discover** - Analyze an algebra signature to find valid grade combinations
2. **Customize** - Edit the generated TOML template with proper names and options
3. **Generate** - Produce optimized Rust code from the specification

## Step 1: Discover Entities

Use the `discover` command to analyze an algebra signature and generate a TOML template:

```bash
# Signature format: "p,q,r" (positive, negative, zero basis vectors)
# For algebras without negative or zero bases, you can omit them

# Euclidean 3D: Cl(3,0,0)
clifford-codegen discover "3,0,0" -o algebras/my_euclidean3.toml

# Projective GA 3D: Cl(3,0,1)
clifford-codegen discover "3,0,1" -o algebras/my_pga3.toml

# Conformal GA 3D: Cl(4,1,0)
clifford-codegen discover "4,1,0" -o algebras/my_cga3.toml

# Print to stdout instead of file
clifford-codegen discover "3,0,0"
```

The discover command outputs:

```toml
# Auto-discovered entities for Cl(3,0,0)
# Generated by clifford-codegen discover
#
# Review and customize:
# - Rename placeholder entities (Entity_*)
# - Add/remove types as needed
# - Customize descriptions
# - Configure constraints

[algebra]
name = ""  # TODO: Fill in algebra name
module_path = ""  # TODO: Fill in module path
description = "Cl(3,0,0)"

[signature]
positive = ["e1", "e2", "e3"]
negative = []
zero = []

# Discovered Types (6 entities satisfy geometric constraints)

[types.Entity_0]
grades = [0]

[types.Entity_1]
grades = [1]

[types.Entity_2]
grades = [2]

[types.Entity_3]
grades = [3]

[types.Entity_0_2]
grades = [0, 2]

[types.Entity_1_3]
grades = [1, 3]
```

### Discovered Entities

The discover command finds the **minimal closed set** of geometric entities:

- **Single-grade elements**: Scalars, vectors, bivectors, etc.
- **Even subalgebra**: Grades 0, 2, 4, ... (rotors/motors live here)
- **Odd subalgebra**: Grades 1, 3, 5, ... (flectors/reflections)

Only grade combinations that satisfy the **geometric constraint** are included.
The geometric constraint requires that `u * ũ` (element times its reverse)
produces only a scalar.

### Field Constraints

Some entities require **field constraints** for the geometric constraint to hold.
For example, PGA bivectors (lines) must satisfy `e01*e23 + e02*e31 + e03*e12 = 0`
for their direction and moment to be orthogonal.

When a constraint is needed, it appears in the TOML:

```toml
[types.Entity_2]
grades = [2]
constraint = "e01*e23 + e02*e31 + e03*e12 = 0"
```

## Step 2: Customize the TOML

Edit the generated TOML to add meaningful names and configure options:

### 1. Fill in Algebra Metadata

```toml
[algebra]
name = "euclidean3"           # Used for module naming
module_path = "euclidean::dim3"  # Rust module path
description = "3D Euclidean Geometric Algebra"
```

### 2. Rename Entity Types

Replace placeholder names with meaningful geometric names:

```toml
# Before
[types.Entity_0]
grades = [0]

[types.Entity_1]
grades = [1]

[types.Entity_0_2]
grades = [0, 2]

# After
[types.Scalar]
grades = [0]
description = "Grade-0 scalar"

[types.Vector]
grades = [1]
description = "Grade-1 vector"

[types.Rotor]
grades = [0, 2]
description = "3D rotation element"
```

### 3. Add Field Names

Map blade names to semantic field names for better ergonomics:

```toml
[blades]
e1 = "x"
e2 = "y"
e3 = "z"
e12 = "xy"
e13 = "xz"
e23 = "yz"
e123 = "xyz"

[types.Vector]
grades = [1]
fields = ["x", "y", "z"]  # Uses blade mappings
```

### 4. Add Constraints

Define unit and nonzero constraints for types that need them:

```toml
[types.Vector]
grades = [1]
fields = ["x", "y", "z"]

[types.Vector.constraints.unit]
# Generates UnitVector wrapper type

[types.Vector.constraints.nonzero]
# Generates NonZeroVector wrapper type

[types.Rotor]
grades = [0, 2]
fields = ["s", "xy", "xz", "yz"]

[types.Rotor.constraints.unit]
# Generates UnitRotor wrapper type
```

### 5. Define Products

Specify which products to generate and their result types:

```toml
[products.geometric]
Vector_Vector = "Rotor"
Rotor_Rotor = "Rotor"
UnitRotor_UnitRotor = "UnitRotor"

[products.outer]
Vector_Vector = "Bivector"
Vector_Bivector = "Trivector"

[products.scalar]
Vector_Vector = "T"  # Returns the scalar type parameter
```

## Step 3: Generate Rust Code

Use the `generate` command to produce Rust code from your specification:

```bash
# Generate to the clifford crate's src directory
clifford-codegen generate algebras/euclidean3.toml -o src/specialized/euclidean/dim3/

# Preview what would be generated
clifford-codegen generate algebras/euclidean3.toml --dry-run

# Overwrite existing files
clifford-codegen generate algebras/euclidean3.toml --force

# With verbose output
clifford-codegen generate algebras/euclidean3.toml -v
```

### Generated Files

The generator creates a Rust module with:

```
my_algebra/
├── mod.rs         # Module re-exports and allow attributes
├── types.rs       # Type definitions (Vector, Bivector, Rotor, etc.)
├── products.rs    # Product implementations (geometric, outer, inner)
├── traits.rs      # Standard trait impls (Debug, Clone, PartialEq, ops)
└── conversions.rs # Multivector conversions
```

### Integrating Generated Code

The generated code is designed to be used **inside the clifford crate**. It uses
`crate::` imports for the `Float` trait, `Multivector`, `Blade`, and signatures.

To integrate generated code:

1. Generate into a subdirectory under `src/`:
   ```bash
   clifford-codegen generate algebras/my_algebra.toml -o src/my_algebra/ --force
   ```

2. Add the module to `src/lib.rs`:
   ```rust
   pub mod my_algebra;
   ```

3. Build and test:
   ```bash
   cargo build
   cargo test my_algebra
   ```

## Complete Example: Creating a 2D Euclidean Algebra

```bash
# 1. Discover entities
clifford-codegen discover "2,0,0" -o algebras/euclidean2.toml

# 2. Edit the TOML (see example below)

# 3. Generate code into the clifford crate
clifford-codegen generate algebras/euclidean2.toml -o src/specialized/euclidean/dim2/ --force

# 4. Add module to lib.rs and test
cargo test specialized::euclidean::dim2
```

Example customized `euclidean2.toml`:

```toml
[algebra]
name = "euclidean2"
module_path = "euclidean::dim2"
description = "2D Euclidean Geometric Algebra"

[signature]
positive = ["e1", "e2"]

[blades]
e1 = "x"
e2 = "y"
e12 = "xy"

[types.Scalar]
grades = [0]
description = "Grade-0 scalar"
fields = ["s"]

[types.Vector]
grades = [1]
description = "Grade-1 vector"
fields = ["x", "y"]

[types.Vector.constraints.unit]
[types.Vector.constraints.nonzero]

[types.Bivector]
grades = [2]
description = "Grade-2 pseudoscalar"
fields = ["xy"]

[types.Rotor]
grades = [0, 2]
description = "2D rotation element"
fields = ["s", "xy"]

[types.Rotor.constraints.unit]

[products.geometric]
Vector_Vector = "Rotor"
Rotor_Rotor = "Rotor"
UnitRotor_UnitRotor = "UnitRotor"

[products.outer]
Vector_Vector = "Bivector"

[products.scalar]
Vector_Vector = "T"
```

## Other Commands

### List Blades

```bash
clifford-codegen blades algebras/euclidean3.toml
clifford-codegen blades algebras/euclidean3.toml --grade 2  # Filter by grade
clifford-codegen blades algebras/euclidean3.toml --format json
```

### List Products

```bash
clifford-codegen products algebras/euclidean3.toml
clifford-codegen products algebras/euclidean3.toml --type Vector
clifford-codegen products algebras/euclidean3.toml --product geometric --table
```

### Verify Generated Code

```bash
clifford-codegen verify src/specialized/euclidean/dim3/ --spec algebras/euclidean3.toml
```

## Common Algebras

| Algebra | Signature | Command |
|---------|-----------|---------|
| Euclidean 2D | Cl(2,0,0) | `discover "2,0,0"` |
| Euclidean 3D | Cl(3,0,0) | `discover "3,0,0"` |
| PGA 2D | Cl(2,0,1) | `discover "2,0,1"` |
| PGA 3D | Cl(3,0,1) | `discover "3,0,1"` |
| CGA 2D | Cl(3,1,0) | `discover "3,1,0"` |
| CGA 3D | Cl(4,1,0) | `discover "4,1,0"` |
| Spacetime | Cl(1,3,0) | `discover "1,3,0"` |