1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! Linear algebra types for mathematical expressions.
/// Notation style for marking vectors.
///
/// Specifies how a vector is visually distinguished in mathematical notation.
/// Different fields use different conventions for marking vectors.
///
/// ## Usage in LaTeX
///
/// - **Bold**: `\mathbf{v}` - Common in physics and engineering
/// - **Arrow**: `\vec{v}` - Traditional notation, common in introductory texts
/// - **Hat**: `\hat{n}` - Typically used for unit vectors
/// - **Underline**: `\underline{v}` - Less common, sometimes used in handwriting
/// - **Plain**: No special notation - relies on context
///
/// ## Examples
///
/// ```
/// use mathlex::ast::VectorNotation;
///
/// let bold = VectorNotation::Bold; // \mathbf{v}
/// let arrow = VectorNotation::Arrow; // \vec{v}
/// let hat = VectorNotation::Hat; // \hat{n}
/// let underline = VectorNotation::Underline; // \underline{v}
/// let plain = VectorNotation::Plain; // v
///
/// assert_ne!(bold, arrow);
/// assert_ne!(arrow, hat);
/// ```
/// Index position type for tensor notation.
///
/// In Einstein summation convention, indices can be either upper (contravariant)
/// or lower (covariant). The position determines how the index transforms under
/// coordinate changes.
///
/// ## Examples
///
/// ```
/// use mathlex::ast::IndexType;
///
/// let upper = IndexType::Upper; // T^i (superscript)
/// let lower = IndexType::Lower; // T_j (subscript)
/// ```
/// A single tensor index with name and position.
///
/// Represents an index in tensor notation, specifying both the index name
/// (typically a single letter like i, j, k) and whether it appears as an
/// upper (contravariant) or lower (covariant) index.
///
/// ## Einstein Summation Convention
///
/// When the same index name appears once as upper and once as lower in a term,
/// summation over that index is implied. For example, `T^i_j v^j` implies
/// `Σ_j T^i_j v^j`.
///
/// ## Examples
///
/// ```
/// use mathlex::ast::{TensorIndex, IndexType};
///
/// // Upper index i (T^i)
/// let upper_i = TensorIndex {
/// name: "i".to_string(),
/// index_type: IndexType::Upper,
/// };
///
/// // Lower index j (T_j)
/// let lower_j = TensorIndex {
/// name: "j".to_string(),
/// index_type: IndexType::Lower,
/// };
/// ```
/// Format tensor indices as upper/lower index strings (e.g., `^{ij}` and `_{k}`).
///
/// Returns a pair `(upper, lower)` where each string is empty if no indices
/// of that type exist, or formatted as `^{names}` / `_{names}` respectively.
pub