Skip to content

Commit ba9d770

Browse files
committed
docs: fix stale README + guides — plural factories, V3 object-init, real PhysicalConstants surface
Sweeps three user-facing docs to match the current generator output: README.md - V0 factory examples already correct on plural (FromMetersPerSecond, FromMeters, FromKilograms, FromNewtons, FromSeconds). - V3 examples (Force3D, Displacement3D) switched from non-existent 3-arg From{Unit}(x, y, z) factories to object-initializer construction with X/Y/Z components, which matches what the generator actually emits. - Magnitude() example now says "Length" rather than "Distance" — the V3 base's Magnitude() returns the V0 base of the dimension, not an overload. - Added a comment showing the construction-time invariants from #50/#51 (Speed.FromMetersPerSecond(-1) and Wavelength.FromMeters(0) both throw ArgumentException). - Removed the aspirational PhysicalConstants.Conversion.X<T>() examples (CLAUDE.md was already cleaned up in #70 but README hadn't been). Replaced with the real domain-grouped / Generic<T>() shape that PhysicalConstantsGenerator emits today. - Architecture section: now lists units.json/magnitudes.json/ conversions.json/domains.json alongside dimensions.json and adds the SEM001/SEM002/SEM003 diagnostic line-up. docs/physics-domains-guide.md - Magnitude / Cross / Dot examples use object-initializer for V3, matching the generated surface. docs/complete-library-guide.md - Same V3 fix. - "mass * Acceleration<double>.FromMeters(9.8)" was nonsense on two counts (Acceleration is a dimension name, not a generated type; Meters is the wrong unit for acceleration). Replaced with the correct AccelerationMagnitude<double>.FromMetersPerSecondSquared(9.8). - Magnitude() example now says "Length" rather than "Distance"; same reason as the README fix. No code or generated output changes; pure docs sync to current API.
1 parent f41624b commit ba9d770

3 files changed

Lines changed: 51 additions & 35 deletions

File tree

README.md

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -99,45 +99,53 @@ Every quantity is a vector. Direction-space dimensionality is part of the type:
9999
```csharp
100100
using ktsu.Semantics.Quantities;
101101

102-
// V0 magnitudes
102+
// V0 magnitudes — From{Unit} factories use the plural form (#49)
103103
var speed = Speed<double>.FromMetersPerSecond(15.0);
104-
var mass = Mass<double>.FromKilogram(10.0);
105-
var distance = Distance<double>.FromMeter(5.0);
104+
var mass = Mass<double>.FromKilograms(10.0);
105+
var distance = Distance<double>.FromMeters(5.0);
106106

107-
// V3 directional
108-
var force3d = Force3D<double>.FromNewton(0.0, 0.0, -9.8);
109-
var disp3d = Displacement3D<double>.FromMeter(3.0, 4.0, 0.0);
107+
// V3 directional — object-initializer syntax (X/Y/Z components)
108+
var force3d = new Force3D<double> { X = 0.0, Y = 0.0, Z = -9.8 };
109+
var disp3d = new Displacement3D<double> { X = 3.0, Y = 4.0, Z = 0.0 };
110110

111111
// Operators flow from dimensions.json
112-
var work = ForceMagnitude<double>.FromNewton(10.0) * distance; // F·d = Energy
113-
var power = work / Duration<double>.FromSecond(2.0); // W/t = Power
112+
var work = ForceMagnitude<double>.FromNewtons(10.0) * distance; // F·d = Energy
113+
var power = work / Duration<double>.FromSeconds(2.0); // W/t = Power
114114
115115
// Vector ops
116116
var workDot = force3d.Dot(disp3d); // Energy
117117
var torque = force3d.Cross(disp3d); // Torque3D
118-
var mag = disp3d.Magnitude(); // Distance (always >= 0)
118+
var mag = disp3d.Magnitude(); // Length (always >= 0)
119+
120+
// Construction-time invariants (#50, #51)
121+
// Speed.FromMetersPerSecond(-1.0) // ArgumentException — V0 must be non-negative
122+
// Wavelength<double>.FromMeters(0.0) // ArgumentException — strict-positive overload
119123
120124
// Type safety
121-
// var nope = force3d + speed; // ❌ compiler error
125+
// var nope = force3d + speed; // ❌ compiler error
122126
```
123127

124128
Semantic overloads (e.g. `Weight` over `ForceMagnitude`, `Diameter``Radius`):
125129

126130
```csharp
127-
var raw = ForceMagnitude<double>.FromNewton(686.0);
131+
var raw = ForceMagnitude<double>.FromNewtons(686.0);
128132
var weight = Weight<double>.From(raw); // explicit narrow
129133
ForceMagnitude<double> back = weight; // implicit widen
130134
131-
var radius = Radius<double>.FromMeter(2.0);
135+
var radius = Radius<double>.FromMeters(2.0);
132136
var diameter = radius.ToDiameter(); // 4 m via metadata-defined relationship
133137
```
134138

135-
Physical constants:
139+
Physical constants are exposed in two shapes:
136140

137141
```csharp
138-
var c = PhysicalConstants.Generic.SpeedOfLight<double>(); // 299_792_458 m/s
139-
var R = PhysicalConstants.Generic.GasConstant<decimal>();
140-
var ftM = PhysicalConstants.Conversion.FeetToMeters<double>(); // 0.3048
142+
// Domain-grouped, exact PreciseNumber values:
143+
PhysicalConstants.Fundamental.SpeedOfLight; // 299_792_458 m/s as PreciseNumber
144+
PhysicalConstants.Chemistry.GasConstant; // 8.31446... J/(mol·K)
145+
146+
// Generic accessors — materialise into any T : INumber<T>:
147+
var c = PhysicalConstants.Generic.SpeedOfLight<double>();
148+
var R = PhysicalConstants.Generic.GasConstant<decimal>();
141149
```
142150

143151
The unified vector model and its rationale: [`docs/strategy-unified-vector-quantities.md`](docs/strategy-unified-vector-quantities.md).
@@ -161,12 +169,18 @@ public class UserService(ISemanticStringFactory<EmailAddress> emails)
161169
## Architecture
162170

163171
The physics system is **metadata-driven**. The single source of truth is
164-
`Semantics.SourceGenerators/Metadata/dimensions.json`, with a Roslyn incremental generator emitting:
172+
`Semantics.SourceGenerators/Metadata/dimensions.json` (with `units.json`, `magnitudes.json`, `conversions.json`, and `domains.json` alongside it), and a Roslyn incremental generator emits:
165173

166174
- One record per quantity (Vector0/1/2/3/4 base + semantic overloads).
167-
- `From{Unit}` factories.
168-
- Cross-dimensional `*`, `/`, `Dot`, `Cross` operators.
169-
- `PhysicalConstants.Generic.X<T>()` and `PhysicalConstants.Conversion.X<T>()`.
175+
- A `From{Unit}` factory per declared unit, with built-in unit conversion to the SI base unit and a `Vector0Guards` enforce-non-negative (or strict-positive) check on V0 types.
176+
- Cross-dimensional `*`, `/`, `Dot`, `Cross` operators driven by `integrals` / `derivatives` / `dotProducts` / `crossProducts` declarations.
177+
- `PhysicalConstants` with both domain-grouped `PreciseNumber` fields and generic `T.CreateChecked`-backed accessors.
178+
179+
Generator diagnostics catch metadata problems at build time:
180+
181+
- **SEM001** — relationship references an unknown dimension name.
182+
- **SEM002** — schema-level metadata issue (missing fields, duplicate type names, etc).
183+
- **SEM003** — relationship's `forms` list references a vector form not declared on a participating dimension.
170184

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

docs/complete-library-guide.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ var energy = Energy<double>.FromJoules(1_000.0);
152152
var v1 = Velocity1D<double>.FromMetersPerSecond(-3.5);
153153
var temp = Temperature<double>.FromKelvins(300.0);
154154

155-
// Vector3 — directional
156-
var force3d = Force3D<double>.FromNewtons(0.0, 0.0, -9.8);
157-
var disp3d = Displacement3D<double>.FromMeters(3.0, 4.0, 0.0);
155+
// Vector3 — directional (object-initializer with X/Y/Z components)
156+
var force3d = new Force3D<double> { X = 0.0, Y = 0.0, Z = -9.8 };
157+
var disp3d = new Displacement3D<double> { X = 3.0, Y = 4.0, Z = 0.0 };
158158
```
159159

160160
### Operators and dimensional analysis
@@ -163,14 +163,14 @@ Cross-dimensional operators are declared in `dimensions.json` and emitted automa
163163

164164
```csharp
165165
// V0 × V0 (magnitudes)
166-
var force = mass * Acceleration<double>.FromMeters(9.8); // Mass × Accel = Force
167-
var work = ForceMagnitude<double>.FromNewtons(10.0) * distance; // F·d = Energy
168-
var power = work / Duration<double>.FromSeconds(2.0); // W/t = Power
166+
var force = mass * AccelerationMagnitude<double>.FromMetersPerSecondSquared(9.8); // Mass × Accel = Force
167+
var work = ForceMagnitude<double>.FromNewtons(10.0) * distance; // F·d = Energy
168+
var power = work / Duration<double>.FromSeconds(2.0); // W/t = Power
169169
170170
// Vector ops
171-
var workScalar = force3d.Dot(disp3d); // Energy
172-
var torque = force3d.Cross(disp3d); // Torque3D
173-
var magnitude = disp3d.Magnitude(); // Distance
171+
var workScalar = force3d.Dot(disp3d); // Energy (V0)
172+
var torque = force3d.Cross(disp3d); // Torque3D (V3)
173+
var magnitude = disp3d.Magnitude(); // Length (V0, always >= 0)
174174
175175
// Type safety
176176
// var nope = force + temp; // ❌ compiler error

docs/physics-domains-guide.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ var temp = Temperature<double>.FromKelvins(298.15);
4343
- `Frequency` — V0 with overloads `SamplingRate`, `BitRate`, `RefreshRate`, `RotationalSpeed`.
4444

4545
```csharp
46-
var velocity3d = Velocity3D<double>.FromMetersPerSecond(3.0, 4.0, 0.0);
46+
// V3 vectors use object-initializer construction (X / Y / Z components)
47+
var velocity3d = new Velocity3D<double> { X = 3.0, Y = 4.0, Z = 0.0 };
4748
var speed = velocity3d.Magnitude(); // 5.0 (Speed<double>)
4849
var sampling = SamplingRate<double>.FromHertz(48_000);
4950
```
@@ -165,23 +166,24 @@ var M = n / V; // Concentration<doub
165166
### Magnitude extraction
166167

167168
```csharp
168-
Velocity3D<double> v = Velocity3D<double>.FromMetersPerSecond(3.0, 4.0, 0.0);
169+
Velocity3D<double> v = new() { X = 3.0, Y = 4.0, Z = 0.0 };
169170
Speed<double> s = v.Magnitude(); // 5.0, always >= 0
170171
```
171172

172173
### Cross product (V3 only)
173174

174175
```csharp
175-
Force3D<double> F = Force3D<double>.FromNewtons(0.0, 10.0, 0.0);
176-
Displacement3D<double> r = Displacement3D<double>.FromMeters(0.5, 0.0, 0.0);
176+
Force3D<double> F = new() { X = 0.0, Y = 10.0, Z = 0.0 };
177+
Displacement3D<double> r = new() { X = 0.5, Y = 0.0, Z = 0.0 };
177178
Torque3D<double> τ = F.Cross(r);
178179
```
179180

180181
### Dot product
181182

182183
```csharp
183-
Energy<double> work = Force3D<double>.FromNewtons(10.0, 0.0, 0.0)
184-
.Dot(Displacement3D<double>.FromMeters(2.0, 0.0, 0.0)); // 20 J
184+
Force3D<double> F = new() { X = 10.0, Y = 0.0, Z = 0.0 };
185+
Displacement3D<double> r = new() { X = 2.0, Y = 0.0, Z = 0.0 };
186+
Energy<double> work = F.Dot(r); // 20 J
185187
```
186188

187189
### Semantic overload narrowing

0 commit comments

Comments
 (0)