Skip to content

Commit 8cb35c7

Browse files
Merge pull request #79 from ktsu-dev/claude/review-vectors-branch-pgIZG
docs(architecture): document physics generator pipeline (closes #61)
2 parents 3ac249f + 00ac9c3 commit 8cb35c7

2 files changed

Lines changed: 61 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ Generator diagnostics catch metadata problems at build time:
181181
- **SEM001** — relationship references an unknown dimension name.
182182
- **SEM002** — schema-level metadata issue (missing fields, duplicate type names, etc).
183183
- **SEM003** — relationship's `forms` list references a vector form not declared on a participating dimension.
184+
- **SEM004**`availableUnits` references a unit not declared in `units.json`.
184185

185186
Generated output is committed to `Semantics.Quantities/Generated/` so the project compiles without first running the generator.
186187

docs/architecture.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Architecture Guide
22

3-
This document provides a detailed overview of the Semantics library architecture, focusing on the SOLID principles and DRY practices implemented throughout the codebase.
3+
This document covers the architecture of the **semantic strings, paths, and validation** subsystems. The physics quantities subsystem is metadata-driven and is documented separately:
4+
5+
- [`docs/strategy-unified-vector-quantities.md`](strategy-unified-vector-quantities.md) — the unified `IVector0..IVector4` model.
6+
- [`docs/physics-generator.md`](physics-generator.md)`dimensions.json` schema and the source-generator pipeline.
7+
- The [Physics Quantities: Metadata-Driven Generation](#physics-quantities-metadata-driven-generation) section below provides a short orientation and links into those documents.
48

59
## Table of Contents
610

@@ -10,11 +14,12 @@ This document provides a detailed overview of the Semantics library architecture
1014
- [Design Patterns](#design-patterns)
1115
- [Class Hierarchy](#class-hierarchy)
1216
- [Validation System](#validation-system)
17+
- [Physics Quantities: Metadata-Driven Generation](#physics-quantities-metadata-driven-generation)
1318
- [Testing Strategy](#testing-strategy)
1419

1520
## Overview
1621

17-
The Semantics library is designed around clean architecture principles, with a focus on maintainability, extensibility, and testability. The core philosophy is to provide type-safe string wrappers while maintaining excellent separation of concerns and avoiding code duplication.
22+
The Semantics library is built around three pillars — **semantic strings**, **semantic paths**, and **physics quantities** — sharing a single philosophy: replace primitive obsession with strongly-typed, self-validating domain models. Strings and paths use a hand-authored attribute → strategy → rule → factory pipeline (described in this document). Physics quantities are emitted at compile time by a Roslyn incremental generator from declarative metadata (described in [Physics Quantities: Metadata-Driven Generation](#physics-quantities-metadata-driven-generation)). All three subsystems target `net10.0`, `net9.0`, `net8.0`, `net7.0`.
1823

1924
## SOLID Principles Implementation
2025

@@ -271,6 +276,59 @@ User Creates Semantic String
271276
Return Valid Object or Throw Exception
272277
```
273278

279+
## Physics Quantities: Metadata-Driven Generation
280+
281+
Unlike strings and paths — which are hand-authored — every physics quantity type, factory, operator, and constant is emitted by a Roslyn incremental generator. The single source of truth is `Semantics.SourceGenerators/Metadata/`:
282+
283+
| File | Contents |
284+
|---|---|
285+
| `dimensions.json` | Every physical dimension, the vector forms it supports (`Vector0`..`Vector4`), its `availableUnits`, semantic overloads (e.g. `Weight` over `ForceMagnitude`), and cross-dimensional relationships (`integrals`, `derivatives`, `dotProducts`, `crossProducts`). |
286+
| `units.json` | Unit declarations with `factoryName` (plural) and a base-unit conversion expression. |
287+
| `magnitudes.json` | SI magnitude prefixes for unit derivations. |
288+
| `conversions.json` | Conversion factors between non-SI units and the SI base. |
289+
| `domains.json` | Domain grouping for `PhysicalConstants` (e.g. `Fundamental`, `Chemistry`, `AngularMechanics`). |
290+
291+
### Generator pipeline
292+
293+
```
294+
Metadata/*.json
295+
296+
297+
Semantics.SourceGenerators (Roslyn IIncrementalGenerator)
298+
299+
├── QuantitiesGenerator → one record per quantity (V0/V1/V2/V3/V4 + overloads)
300+
│ + From{Unit} factory per declared unit
301+
│ + Vector0Guards.EnsureNonNegative / EnsurePositive
302+
│ + cross-dimensional *, /, Dot, Cross operators
303+
├── ConversionsGenerator → unit-to-SI conversion helpers
304+
├── PhysicalConstantsGenerator → PhysicalConstants.<Domain>.* (PreciseNumber)
305+
│ + PhysicalConstants.Generic.*<T>() (T.CreateChecked)
306+
└── StorageHelpersGenerator → DivideToStorage with DivideByZeroException
307+
308+
309+
Semantics.Quantities/Generated/ (committed source — diff before commit)
310+
```
311+
312+
### Vector-form invariants
313+
314+
These are enforced structurally by the generated types and locked in by `Semantics.Test`:
315+
316+
1. `V0` magnitudes are non-negative; the SI factory throws `ArgumentException` on a negative value, and `V0 - V0` returns `T.Abs(a - b)` to preserve the invariant.
317+
2. A V0 overload can opt into a strict-positive guard with `physicalConstraints: { "minExclusive": "0" }` (used by `Wavelength`, `Period`, `HalfLife`); `EnsurePositive` then rejects zero as well.
318+
3. Semantic overloads widen implicitly to their base, narrow explicitly (`Weight.From(forceMagnitude)`).
319+
4. `IVectorN.Magnitude()` for N ≥ 1 returns the corresponding `IVector0`.
320+
321+
### Generator diagnostics
322+
323+
Metadata errors fail the build rather than silently emitting wrong code:
324+
325+
- **SEM001** — a relationship references a dimension that does not exist.
326+
- **SEM002** — schema-level metadata issue (missing `name` / `symbol`, empty `availableUnits`, duplicate type names, no vector forms declared).
327+
- **SEM003** — a relationship's explicit `forms` list references a vector form not declared on a participating dimension.
328+
- **SEM004** — a dimension's `availableUnits` array references a unit name that isn't declared in `units.json` (catches typos that would otherwise produce a wrong identity-conversion factory).
329+
330+
For the schema, an end-to-end "add a dimension" walk-through, and the design rationale, see [`docs/physics-generator.md`](physics-generator.md) and [`docs/strategy-unified-vector-quantities.md`](strategy-unified-vector-quantities.md).
331+
274332
## Testing Strategy
275333

276334
### Contract Testing

0 commit comments

Comments
 (0)