Skip to main content

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//! - `i64`, `f64`, and `rational` reach `complex`; `complex` is the scalar
27//!   numeric sink before symbolic, function, or tensor lifting.
28//! - `cas` absorbs scalar domains through value promotion so symbolic
29//!   arithmetic can mix CAS values with installed numeric domains.
30//! - `tensor` is value-only; tensor broadcast and typed tensor fast paths use
31//!   explicit value descriptors rather than scalar promotion.
32
33use sim_kernel::Symbol;
34
35/// Build a symbol in the canonical `numbers` namespace.
36pub fn domain(name: impl Into<String>) -> Symbol {
37    Symbol::qualified("numbers", name.into())
38}
39
40/// The `numbers/arith` symbol: the cross-domain arithmetic op namespace.
41pub fn arith() -> Symbol {
42    domain("arith")
43}
44
45/// The `numbers/bool` domain symbol.
46pub fn bool() -> Symbol {
47    domain("bool")
48}
49
50/// The `numbers/i8` domain symbol.
51pub fn i8() -> Symbol {
52    domain("i8")
53}
54
55/// The `numbers/u8` domain symbol.
56pub fn u8() -> Symbol {
57    domain("u8")
58}
59
60/// The `numbers/i16` domain symbol.
61pub fn i16() -> Symbol {
62    domain("i16")
63}
64
65/// The `numbers/u16` domain symbol.
66pub fn u16() -> Symbol {
67    domain("u16")
68}
69
70/// The `numbers/i32` domain symbol.
71pub fn i32() -> Symbol {
72    domain("i32")
73}
74
75/// The `numbers/u32` domain symbol.
76pub fn u32() -> Symbol {
77    domain("u32")
78}
79
80/// The `numbers/i64` domain symbol.
81pub fn i64() -> Symbol {
82    domain("i64")
83}
84
85/// The `numbers/u64` domain symbol.
86pub fn u64() -> Symbol {
87    domain("u64")
88}
89
90/// The `numbers/i128` domain symbol.
91pub fn i128() -> Symbol {
92    domain("i128")
93}
94
95/// The `numbers/u128` domain symbol.
96pub fn u128() -> Symbol {
97    domain("u128")
98}
99
100/// The `numbers/isize` domain symbol.
101pub fn isize() -> Symbol {
102    domain("isize")
103}
104
105/// The `numbers/usize` domain symbol.
106pub fn usize() -> Symbol {
107    domain("usize")
108}
109
110/// The `numbers/f32` domain symbol.
111pub fn f32() -> Symbol {
112    domain("f32")
113}
114
115/// The `numbers/f64` domain symbol.
116pub fn f64() -> Symbol {
117    domain("f64")
118}
119
120/// The `numbers/fixed` fixed-point domain symbol.
121pub fn fixed() -> Symbol {
122    domain("fixed")
123}
124
125/// The `numbers/bigint` arbitrary-precision integer domain symbol.
126pub fn bigint() -> Symbol {
127    domain("bigint")
128}
129
130/// The `numbers/rational` domain symbol.
131pub fn rational() -> Symbol {
132    domain("rational")
133}
134
135/// The `numbers/complex` domain symbol (the scalar numeric sink).
136pub fn complex() -> Symbol {
137    domain("complex")
138}
139
140/// The `numbers/cf` continued-fraction domain symbol.
141pub fn continued_fraction() -> Symbol {
142    domain("cf")
143}
144
145/// The `numbers/cas` symbolic (computer-algebra) domain symbol.
146pub fn cas() -> Symbol {
147    domain("cas")
148}
149
150/// The `numbers/cas-diff` symbolic-differentiation domain symbol.
151pub fn cas_diff() -> Symbol {
152    domain("cas-diff")
153}
154
155/// The `numbers/cas-eval` symbolic-evaluation domain symbol.
156pub fn cas_eval() -> Symbol {
157    domain("cas-eval")
158}
159
160/// The `numbers/func` function-value domain symbol.
161pub fn func() -> Symbol {
162    domain("func")
163}
164
165/// The `numbers/tensor` domain symbol (value-only lift over scalar domains).
166pub fn tensor() -> Symbol {
167    domain("tensor")
168}
169
170/// The `numbers/tensor-bcast` broadcasting tensor domain symbol.
171pub fn tensor_bcast() -> Symbol {
172    domain("tensor-bcast")
173}
174
175/// The `numbers/tensor-linalg` linear-algebra tensor domain symbol.
176pub fn tensor_linalg() -> Symbol {
177    domain("tensor-linalg")
178}
179
180/// The `numbers/numeric` namespace symbol for numeric utilities.
181pub fn numeric() -> Symbol {
182    domain("numeric")
183}
184
185/// The `numbers/quad` quadrature (numeric integration) domain symbol.
186pub fn quad() -> Symbol {
187    domain("quad")
188}
189
190/// The `numbers/rk` Runge-Kutta (numeric ODE) domain symbol.
191pub fn rk() -> Symbol {
192    domain("rk")
193}
194
195/// The literal-class symbol for a domain, e.g. `numbers/i64-literal`.
196///
197/// # Examples
198///
199/// ```
200/// use sim_lib_numbers_core::domains;
201///
202/// assert_eq!(
203///     domains::literal_class("i64"),
204///     domains::domain("i64-literal"),
205/// );
206/// ```
207pub fn literal_class(domain_name: impl AsRef<str>) -> Symbol {
208    domain(format!("{}-literal", domain_name.as_ref()))
209}
210
211/// The value-shape symbol for `domain`, e.g. `numbers/i64/value-shape`.
212pub fn value_shape(domain: &Symbol) -> Symbol {
213    Symbol::qualified(domain.to_string(), "value-shape")
214}
215
216/// The `numbers/Rational` value-class symbol.
217pub fn rational_value_class() -> Symbol {
218    domain("Rational")
219}
220
221/// The `numbers/Complex` value-class symbol.
222pub fn complex_value_class() -> Symbol {
223    domain("Complex")
224}
225
226/// The `numbers/Cas` value-class symbol.
227pub fn cas_value_class() -> Symbol {
228    domain("Cas")
229}
230
231/// The `numbers/Tensor` value-class symbol.
232pub fn tensor_value_class() -> Symbol {
233    domain("Tensor")
234}
235
236/// All fixed-width integer domain symbols (`i8`..`usize`), in lattice order.
237pub fn fixed_integer_domains() -> Vec<Symbol> {
238    [
239        i8(),
240        u8(),
241        i16(),
242        u16(),
243        i32(),
244        u32(),
245        i64(),
246        u64(),
247        i128(),
248        u128(),
249        isize(),
250        usize(),
251    ]
252    .into()
253}
254
255/// All integer domain symbols: the fixed-width set plus `numbers/bigint`.
256///
257/// # Examples
258///
259/// ```
260/// use sim_lib_numbers_core::domains;
261///
262/// let ints = domains::integer_domains();
263/// assert_eq!(ints.len(), domains::fixed_integer_domains().len() + 1);
264/// assert!(ints.contains(&domains::bigint()));
265/// ```
266pub fn integer_domains() -> Vec<Symbol> {
267    let mut domains = fixed_integer_domains();
268    domains.push(bigint());
269    domains
270}