1use crate::structure::*;
2use algebraeon_sets::structure::*;
3use std::{borrow::Cow, marker::PhantomData};
4
5#[derive(Debug, Clone)]
6pub struct FreeModuleOverOrderedSetStructure<
7 Set: OrdSignature,
8 SetB: BorrowedStructure<Set>,
9 Ring: SemiRingSignature,
10 RingB: BorrowedStructure<Ring>,
11> {
12 _set: PhantomData<Set>,
13 set: SetB,
14 _ring: PhantomData<Ring>,
15 ring: RingB,
16}
17
18impl<
19 Set: OrdSignature,
20 SetB: BorrowedStructure<Set>,
21 Ring: SemiRingSignature,
22 RingB: BorrowedStructure<Ring>,
23> PartialEq for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
24{
25 fn eq(&self, other: &Self) -> bool {
26 self.set == other.set && self.ring == other.ring
27 }
28}
29
30impl<
31 Set: OrdSignature,
32 SetB: BorrowedStructure<Set>,
33 Ring: SemiRingSignature,
34 RingB: BorrowedStructure<Ring>,
35> Eq for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
36{
37}
38
39impl<
40 Set: OrdSignature,
41 SetB: BorrowedStructure<Set>,
42 Ring: SemiRingSignature + EqSignature,
43 RingB: BorrowedStructure<Ring>,
44> FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
45{
46 pub fn new(set: SetB, ring: RingB) -> Self {
47 Self {
48 _set: PhantomData,
49 set,
50 _ring: PhantomData,
51 ring,
52 }
53 }
54
55 pub fn set(&self) -> &Set {
56 self.set.borrow()
57 }
58
59 pub fn collapse_terms(&self, v: <Self as SetSignature>::Set) -> <Self as SetSignature>::Set {
67 let mut v = self.set().sort_by_key(v, &|(x, _)| x).into_iter();
68
69 let mut current_x = None;
70 let mut current_a = self.ring().zero();
71
72 let mut w = vec![];
73 loop {
74 enum ItemResult<S, R> {
75 Same(R),
76 Change(S, R),
77 End,
78 }
79
80 let result = if let Some((x, a)) = v.next() {
81 if let Some(current_x) = current_x.as_ref() {
82 if self.set().equal(current_x, &x) {
83 ItemResult::Same(a)
84 } else {
85 ItemResult::Change(x, a)
86 }
87 } else {
88 current_x = Some(x);
89 ItemResult::Same(a)
90 }
91 } else {
92 ItemResult::End
93 };
94
95 match result {
96 ItemResult::Same(a) => {
97 self.ring().add_mut(&mut current_a, &a);
98 }
99 ItemResult::Change(x, a) => {
100 w.push((current_x.unwrap(), current_a));
101 current_x = Some(x);
102 current_a = a;
103 }
104 ItemResult::End => {
105 w.push((current_x.unwrap(), current_a));
106 break;
107 }
108 }
109 }
110 let w = w
111 .into_iter()
112 .filter(|(_, a)| !self.ring().is_zero(a))
113 .collect();
114 debug_assert!(self.is_element(&w).is_ok());
115 w
116 }
117}
118
119impl<
120 Set: OrdSignature,
121 SetB: BorrowedStructure<Set>,
122 Ring: SemiRingSignature,
123 RingB: BorrowedStructure<Ring>,
124> Signature for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
125{
126}
127
128impl<
129 Set: OrdSignature,
130 SetB: BorrowedStructure<Set>,
131 Ring: SemiRingSignature + EqSignature,
132 RingB: BorrowedStructure<Ring>,
133> SetSignature for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
134{
135 type Set = Vec<(Set::Set, Ring::Set)>;
138
139 fn is_element(&self, v: &Self::Set) -> Result<(), String> {
140 if !self.set().is_sorted_and_unique_by_key(v, |(x, _)| x) {
141 return Err("not sorted or has duplicate".to_string());
142 }
143 for (_, a) in v {
144 if self.ring().is_zero(a) {
145 return Err("multiplicity zero".to_string());
146 }
147 }
148 Ok(())
149 }
150}
151
152impl<
153 Set: OrdSignature,
154 SetB: BorrowedStructure<Set>,
155 Ring: SemiRingSignature + EqSignature,
156 RingB: BorrowedStructure<Ring>,
157> EqSignature for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
158{
159 fn equal(&self, v: &Self::Set, w: &Self::Set) -> bool {
160 debug_assert!(self.is_element(v).is_ok());
161 debug_assert!(self.is_element(w).is_ok());
162 let n = v.len();
164 if n != w.len() {
165 false
166 } else {
167 (0..n).all(|i| {
168 let (vx, va) = &v[i];
169 let (wx, wa) = &w[i];
170 self.set().equal(vx, wx) && self.ring().equal(va, wa)
171 })
172 }
173 }
174}
175
176impl<
177 Set: OrdSignature,
178 SetB: BorrowedStructure<Set>,
179 Ring: SemiRingSignature + EqSignature,
180 RingB: BorrowedStructure<Ring>,
181> RinglikeSpecializationSignature for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
182{
183}
184
185impl<
186 Set: OrdSignature,
187 SetB: BorrowedStructure<Set>,
188 Ring: SemiRingSignature + EqSignature,
189 RingB: BorrowedStructure<Ring>,
190> ZeroSignature for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
191{
192 fn zero(&self) -> Self::Set {
193 vec![]
194 }
195}
196
197impl<
198 Set: OrdSignature,
199 SetB: BorrowedStructure<Set>,
200 Ring: SemiRingSignature + EqSignature,
201 RingB: BorrowedStructure<Ring>,
202> AdditionSignature for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
203{
204 fn add(&self, v: &Self::Set, w: &Self::Set) -> Self::Set {
205 self.collapse_terms(v.iter().chain(w.iter()).cloned().collect())
206 }
207}
208
209impl<
210 Set: OrdSignature,
211 SetB: BorrowedStructure<Set>,
212 Ring: SemiRingSignature + EqSignature,
213 RingB: BorrowedStructure<Ring>,
214> CancellativeAdditionSignature for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
215{
216 fn try_sub(&self, _a: &Self::Set, _b: &Self::Set) -> Option<Self::Set> {
217 todo!()
218 }
219}
220
221impl<
222 Set: OrdSignature,
223 SetB: BorrowedStructure<Set>,
224 Ring: SemiRingSignature + EqSignature,
225 RingB: BorrowedStructure<Ring>,
226> TryNegateSignature for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
227{
228 fn try_neg(&self, v: &Self::Set) -> Option<Self::Set> {
229 v.iter()
230 .map(|(x, a)| Some((x.clone(), self.ring().try_neg(a)?)))
231 .collect::<Option<_>>()
232 }
233}
234
235impl<
236 Set: OrdSignature,
237 SetB: BorrowedStructure<Set>,
238 Ring: SemiRingSignature + EqSignature,
239 RingB: BorrowedStructure<Ring>,
240> AdditiveMonoidSignature for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
241{
242}
243
244impl<
245 Set: OrdSignature,
246 SetB: BorrowedStructure<Set>,
247 Ring: RingSignature + EqSignature,
248 RingB: BorrowedStructure<Ring>,
249> AdditiveGroupSignature for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
250{
251 fn neg(&self, v: &Self::Set) -> Self::Set {
252 v.iter()
253 .map(|(x, a)| (x.clone(), self.ring().neg(a)))
254 .collect()
255 }
256}
257
258impl<
259 Set: OrdSignature,
260 SetB: BorrowedStructure<Set>,
261 Ring: SemiRingSignature + EqSignature,
262 RingB: BorrowedStructure<Ring>,
263> SemiModuleSignature<Ring> for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
264{
265 fn ring(&self) -> &Ring {
266 self.ring.borrow()
267 }
268
269 fn scalar_mul(&self, v: &Self::Set, b: &Ring::Set) -> Self::Set {
270 v.iter()
271 .map(|(x, a)| (x.clone(), self.ring().mul(a, b)))
272 .filter(|(_, a)| !self.ring().is_zero(a))
273 .collect()
274 }
275}
276
277impl<
278 Set: OrdSignature,
279 SetB: BorrowedStructure<Set>,
280 Ring: RingSignature + EqSignature,
281 RingB: BorrowedStructure<Ring>,
282> FreeModuleSignature<Ring> for FreeModuleOverOrderedSetStructure<Set, SetB, Ring, RingB>
283{
284 type Basis = Set;
285
286 fn basis_set(&self) -> impl std::borrow::Borrow<Set> {
287 self.set()
288 }
289
290 fn to_component<'a>(&self, x: &Set::Set, v: &'a Self::Set) -> Cow<'a, Ring::Set> {
291 if let Some((_, a)) = self.set().binary_search_by_key(v, x, |(x, _)| x) {
292 Cow::Borrowed(a)
293 } else {
294 Cow::Owned(self.ring().zero())
295 }
296 }
297
298 fn from_component(&self, x: &Set::Set, a: &Ring::Set) -> Self::Set {
299 if self.ring().is_zero(a) {
300 vec![]
301 } else {
302 vec![(x.clone(), a.clone())]
303 }
304 }
305}
306
307#[cfg(test)]
308mod tests {
309 use algebraeon_nzq::{Integer, Natural};
310 use algebraeon_sets::structure::MetaType;
311
312 use super::FreeModuleOverOrderedSetStructure;
313
314 #[test]
315 fn test_ordered_set_free_module() {
316 let m = FreeModuleOverOrderedSetStructure::new(Natural::structure(), Integer::structure());
317
318 let v = vec![
319 (0u32.into(), 1.into()),
320 (1u32.into(), 1.into()),
321 (0u32.into(), (-1).into()),
322 (1u32.into(), 1.into()),
323 ];
324 let w = m.collapse_terms(v);
325 assert_eq!(w, vec![(1u32.into(), 2.into())]);
326 }
327}