sim_lib_numbers_core/domains.rs
1//! Canonical symbols for the number-domain family.
2//!
3//! Concrete number crates should import these helpers instead of spelling
4//! `Symbol::qualified("numbers", "...")` locally. Keeping the symbols in one
5//! place makes promotion edges auditable: a typo cannot silently create an
6//! unreachable domain.
7//!
8//! # Promotion lattice
9//!
10//! The default number prelude installs a directed promotion graph. Literal
11//! promotion rules are a fast path; every edge that participates in dispatch
12//! also has a value-promotion rule so opaque number values can move through the
13//! same lattice.
14//!
15//! Intended scalar reachability:
16//!
17//! - `bool -> u8 -> ...`, plus direct `bool -> i64` and `bool -> f64` edges.
18//! - Signed fixed-width integers widen through `i8 -> i16 -> i32 -> i64 ->
19//! i128`; unsigned fixed-width integers widen through `u8 -> u16 -> u32 ->
20//! u64 -> u128` and can cross to the next wider signed domain.
21//! - Fixed-width integers reach `f32`, `f64`, and `rational`; `i64` also
22//! provides direct `i64 -> f64` and `i64 -> rational` edges.
23//! - `bigint` is the arbitrary-precision integer domain and reaches
24//! `rational`.
25//! - `f32 -> f64`; `f64 <-> rational` when decimal rationalization succeeds.
26//! - `f64 -> extended` and `rational -> extended`; conversion back to `f64` is
27//! explicit because it can discard the low component.
28//! - `i64`, `f64`, and `rational` reach `complex`; `complex` is the scalar
29//! numeric sink before symbolic, function, or tensor lifting.
30//! - `cas` absorbs scalar domains through value promotion so symbolic
31//! arithmetic can mix CAS values with installed numeric domains.
32//! - `tensor` is value-only; tensor broadcast and typed tensor fast paths use
33//! explicit value descriptors rather than scalar promotion.
34
35use sim_kernel::Symbol;
36
37/// Build a symbol in the canonical `numbers` namespace.
38pub fn domain(name: impl Into<String>) -> Symbol {
39 Symbol::qualified("numbers", name.into())
40}
41
42/// The `numbers/arith` symbol: the cross-domain arithmetic op namespace.
43pub fn arith() -> Symbol {
44 domain("arith")
45}
46
47/// The `numbers/bool` domain symbol.
48pub fn bool() -> Symbol {
49 domain("bool")
50}
51
52/// The `numbers/i8` domain symbol.
53pub fn i8() -> Symbol {
54 domain("i8")
55}
56
57/// The `numbers/u8` domain symbol.
58pub fn u8() -> Symbol {
59 domain("u8")
60}
61
62/// The `numbers/i16` domain symbol.
63pub fn i16() -> Symbol {
64 domain("i16")
65}
66
67/// The `numbers/u16` domain symbol.
68pub fn u16() -> Symbol {
69 domain("u16")
70}
71
72/// The `numbers/i32` domain symbol.
73pub fn i32() -> Symbol {
74 domain("i32")
75}
76
77/// The `numbers/u32` domain symbol.
78pub fn u32() -> Symbol {
79 domain("u32")
80}
81
82/// The `numbers/i64` domain symbol.
83pub fn i64() -> Symbol {
84 domain("i64")
85}
86
87/// The `numbers/u64` domain symbol.
88pub fn u64() -> Symbol {
89 domain("u64")
90}
91
92/// The `numbers/i128` domain symbol.
93pub fn i128() -> Symbol {
94 domain("i128")
95}
96
97/// The `numbers/u128` domain symbol.
98pub fn u128() -> Symbol {
99 domain("u128")
100}
101
102/// The `numbers/isize` domain symbol.
103pub fn isize() -> Symbol {
104 domain("isize")
105}
106
107/// The `numbers/usize` domain symbol.
108pub fn usize() -> Symbol {
109 domain("usize")
110}
111
112/// The `numbers/f32` domain symbol.
113pub fn f32() -> Symbol {
114 domain("f32")
115}
116
117/// The `numbers/f16` domain symbol.
118pub fn f16() -> Symbol {
119 domain("f16")
120}
121
122/// The `numbers/bf16` domain symbol.
123pub fn bf16() -> Symbol {
124 domain("bf16")
125}
126
127/// The `numbers/f64` domain symbol.
128pub fn f64() -> Symbol {
129 domain("f64")
130}
131
132/// The `numbers/extended` normalized double-double domain symbol.
133pub fn extended() -> Symbol {
134 domain("extended")
135}
136
137/// The `numbers/fixed` fixed-point domain symbol.
138pub fn fixed() -> Symbol {
139 domain("fixed")
140}
141
142/// The `numbers/bigint` arbitrary-precision integer domain symbol.
143pub fn bigint() -> Symbol {
144 domain("bigint")
145}
146
147/// The `numbers/rational` domain symbol.
148pub fn rational() -> Symbol {
149 domain("rational")
150}
151
152/// The `numbers/complex` domain symbol (the scalar numeric sink).
153pub fn complex() -> Symbol {
154 domain("complex")
155}
156
157/// The `numbers/cf` continued-fraction domain symbol.
158pub fn continued_fraction() -> Symbol {
159 domain("cf")
160}
161
162/// The `numbers/cas` symbolic (computer-algebra) domain symbol.
163pub fn cas() -> Symbol {
164 domain("cas")
165}
166
167/// The `numbers/cas-diff` symbolic-differentiation domain symbol.
168pub fn cas_diff() -> Symbol {
169 domain("cas-diff")
170}
171
172/// The `numbers/cas-eval` symbolic-evaluation domain symbol.
173pub fn cas_eval() -> Symbol {
174 domain("cas-eval")
175}
176
177/// The `numbers/func` function-value domain symbol.
178pub fn func() -> Symbol {
179 domain("func")
180}
181
182/// The `numbers/tensor` domain symbol (value-only lift over scalar domains).
183pub fn tensor() -> Symbol {
184 domain("tensor")
185}
186
187/// The `numbers/tensor-bcast` broadcasting tensor domain symbol.
188pub fn tensor_bcast() -> Symbol {
189 domain("tensor-bcast")
190}
191
192/// The `numbers/tensor-linalg` linear-algebra tensor domain symbol.
193pub fn tensor_linalg() -> Symbol {
194 domain("tensor-linalg")
195}
196
197/// The `numbers/tensor-decomp` factorization domain symbol.
198pub fn tensor_decomp() -> Symbol {
199 domain("tensor-decomp")
200}
201
202/// The `numbers/numeric` namespace symbol for numeric utilities.
203pub fn numeric() -> Symbol {
204 domain("numeric")
205}
206
207/// The `numbers/quad` quadrature (numeric integration) domain symbol.
208pub fn quad() -> Symbol {
209 domain("quad")
210}
211
212/// The `numbers/rk` Runge-Kutta (numeric ODE) domain symbol.
213pub fn rk() -> Symbol {
214 domain("rk")
215}
216
217/// The literal-class symbol for a domain, e.g. `numbers/i64-literal`.
218///
219/// # Examples
220///
221/// ```
222/// use sim_lib_numbers_core::domains;
223///
224/// assert_eq!(
225/// domains::literal_class("i64"),
226/// domains::domain("i64-literal"),
227/// );
228/// ```
229pub fn literal_class(domain_name: impl AsRef<str>) -> Symbol {
230 domain(format!("{}-literal", domain_name.as_ref()))
231}
232
233/// The value-shape symbol for `domain`, e.g. `numbers/i64/value-shape`.
234pub fn value_shape(domain: &Symbol) -> Symbol {
235 Symbol::qualified(domain.to_string(), "value-shape")
236}
237
238/// The `numbers/Rational` value-class symbol.
239pub fn rational_value_class() -> Symbol {
240 domain("Rational")
241}
242
243/// The `numbers/Complex` value-class symbol.
244pub fn complex_value_class() -> Symbol {
245 domain("Complex")
246}
247
248/// The `numbers/Cas` value-class symbol.
249pub fn cas_value_class() -> Symbol {
250 domain("Cas")
251}
252
253/// The `numbers/Tensor` value-class symbol.
254pub fn tensor_value_class() -> Symbol {
255 domain("Tensor")
256}
257
258/// All fixed-width integer domain symbols (`i8`..`usize`), in lattice order.
259pub fn fixed_integer_domains() -> Vec<Symbol> {
260 [
261 i8(),
262 u8(),
263 i16(),
264 u16(),
265 i32(),
266 u32(),
267 i64(),
268 u64(),
269 i128(),
270 u128(),
271 isize(),
272 usize(),
273 ]
274 .into()
275}
276
277/// All integer domain symbols: the fixed-width set plus `numbers/bigint`.
278///
279/// # Examples
280///
281/// ```
282/// use sim_lib_numbers_core::domains;
283///
284/// let ints = domains::integer_domains();
285/// assert_eq!(ints.len(), domains::fixed_integer_domains().len() + 1);
286/// assert!(ints.contains(&domains::bigint()));
287/// ```
288pub fn integer_domains() -> Vec<Symbol> {
289 let mut domains = fixed_integer_domains();
290 domains.push(bigint());
291 domains
292}