1
2use std::collections::{HashMap, HashSet};
3use std::hash::Hash;
4
5#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
23pub enum AlgebraicResult<V> {
24 #[default]
26 None,
27 Identity(u64),
31 Element(V),
33}
34
35pub const SELF_IDENT: u64 = 0x1;
37
38pub const COUNTER_IDENT: u64 = 0x2;
40
41impl<V> AlgebraicResult<V> {
42 #[inline]
44 pub fn is_none(&self) -> bool {
45 matches!(self, AlgebraicResult::None)
46 }
47 #[inline]
49 pub fn is_identity(&self) -> bool {
50 matches!(self, AlgebraicResult::Identity(_))
51 }
52 #[inline]
54 pub fn is_element(&self) -> bool {
55 matches!(self, AlgebraicResult::Element(_))
56 }
57 #[inline]
59 pub fn identity_mask(&self) -> Option<u64> {
60 match self {
61 Self::None => None,
62 Self::Identity(mask) => Some(*mask),
63 Self::Element(_) => None,
64 }
65 }
66 #[inline]
71 pub fn invert_identity(self) -> Self {
72 match self {
73 Self::None => AlgebraicResult::None,
74 Self::Identity(mask) => {
75 let new_mask = ((mask & SELF_IDENT) << 1) | ((mask & COUNTER_IDENT) >> 1);
76 AlgebraicResult::Identity(new_mask)
77 },
78 Self::Element(v) => AlgebraicResult::Element(v),
79 }
80 }
81 #[inline]
84 pub fn map<U, F>(self, f: F) -> AlgebraicResult<U>
85 where F: FnOnce(V) -> U,
86 {
87 match self {
88 Self::None => AlgebraicResult::None,
89 Self::Identity(mask) => AlgebraicResult::Identity(mask),
90 Self::Element(v) => AlgebraicResult::Element(f(v)),
91 }
92 }
93 #[inline]
95 pub fn as_ref(&self) -> AlgebraicResult<&V> {
96 match *self {
97 Self::Element(ref v) => AlgebraicResult::Element(v),
98 Self::None => AlgebraicResult::None,
99 Self::Identity(mask) => AlgebraicResult::Identity(mask),
100 }
101 }
102 #[inline]
107 pub fn map_into_option<IdentF>(self, ident_f: IdentF) -> Option<V>
108 where IdentF: FnOnce(usize) -> Option<V>
109 {
110 match self {
111 Self::Element(v) => Some(v),
112 Self::None => None,
113 Self::Identity(mask) => ident_f(mask.trailing_zeros() as usize),
114 }
115 }
116 #[inline]
119 pub fn into_option<I: AsRef<[VRef]>, VRef: std::borrow::Borrow<V>>(self, idents: I) -> Option<V>
120 where V: Clone
121 {
122 match self {
123 Self::Element(v) => Some(v),
124 Self::None => None,
125 Self::Identity(mask) => {
126 let idents = idents.as_ref();
127 Some(idents[mask.trailing_zeros() as usize].borrow().clone())
128 },
129 }
130 }
131
132 #[inline]
135 pub fn unwrap<I: AsRef<[VRef]>, VRef: std::borrow::Borrow<V>>(self, idents: I) -> V
136 where V: Clone
137 {
138 match self {
139 Self::Element(v) => v,
140 Self::None => panic!(),
141 Self::Identity(mask) => {
142 let idents = idents.as_ref();
143 idents[mask.trailing_zeros() as usize].borrow().clone()
144 },
145 }
146 }
147 #[inline]
151 pub fn unwrap_or_else<IdentF, NoneF>(self, ident_f: IdentF, none_f: NoneF) -> V
152 where
153 IdentF: FnOnce(usize) -> V,
154 NoneF: FnOnce() -> V
155 {
156 match self {
157 Self::Element(v) => v,
158 Self::None => none_f(),
159 Self::Identity(mask) => ident_f(mask.trailing_zeros() as usize),
160 }
161 }
162 #[inline]
164 pub fn unwrap_or<I: AsRef<[VRef]>, VRef: std::borrow::Borrow<V>>(self, idents: I, none: V) -> V
165 where V: Clone
166 {
167 match self {
168 Self::Element(v) => v,
169 Self::None => none,
170 Self::Identity(mask) => {
171 let idents = idents.as_ref();
172 idents[mask.trailing_zeros() as usize].borrow().clone()
173 },
174 }
175 }
176 #[inline]
216 pub fn merge<BV, U, MergeF, AIdent, BIdent>(self, b: AlgebraicResult<BV>, self_idents: AIdent, b_idents: BIdent, merge_f: MergeF) -> AlgebraicResult<U>
217 where
218 MergeF: FnOnce(Option<V>, Option<BV>) -> AlgebraicResult<U>,
219 AIdent: FnOnce(usize) -> Option<V>,
220 BIdent: FnOnce(usize) -> Option<BV>,
221 {
222 match self {
223 Self::None => {
224 match b {
225 AlgebraicResult::None => AlgebraicResult::None,
226 AlgebraicResult::Element(b_v) => merge_f(None, Some(b_v)),
227 AlgebraicResult::Identity(b_mask) => {
228 let self_ident = self_idents(0);
229 if self_ident.is_none() {
230 AlgebraicResult::Identity(b_mask)
231 } else {
232 let b_v = b_idents(b_mask.trailing_zeros() as usize);
233 merge_f(None, b_v)
234 }
235 },
236 }
237 },
238 Self::Identity(self_mask) => {
239 match b {
240 AlgebraicResult::None => {
241 let b_ident = b_idents(0);
242 if b_ident.is_none() {
243 AlgebraicResult::Identity(self_mask)
244 } else {
245 let self_v = self_idents(self_mask.trailing_zeros() as usize);
246 merge_f(self_v, None)
247 }
248 },
249 AlgebraicResult::Element(b_v) => {
250 let self_v = self_idents(self_mask.trailing_zeros() as usize);
251 merge_f(self_v, Some(b_v))
252 },
253 AlgebraicResult::Identity(b_mask) => {
254 let combined_mask = self_mask & b_mask;
255 if combined_mask > 0 {
256 AlgebraicResult::Identity(combined_mask)
257 } else {
258 let self_v = self_idents(self_mask.trailing_zeros() as usize);
259 let b_v = b_idents(b_mask.trailing_zeros() as usize);
260 merge_f(self_v, b_v)
261 }
262 }
263 }
264 },
265 Self::Element(self_v) => {
266 match b {
267 AlgebraicResult::None => merge_f(Some(self_v), None),
268 AlgebraicResult::Element(b_v) => merge_f(Some(self_v), Some(b_v)),
269 AlgebraicResult::Identity(b_mask) => {
270 let b_v = b_idents(b_mask.trailing_zeros() as usize);
271 merge_f(Some(self_v), b_v)
272 }
273 }
274 }
275 }
276 }
277 #[inline]
279 pub fn from_status<F>(status: AlgebraicStatus, element_f: F) -> Self
280 where F: FnOnce() -> V
281 {
282 match status {
283 AlgebraicStatus::None => Self::None,
284 AlgebraicStatus::Identity => Self::Identity(SELF_IDENT),
285 AlgebraicStatus::Element => Self::Element(element_f())
286 }
287 }
288 #[inline]
290 pub fn status(&self) -> AlgebraicStatus {
291 match self {
292 AlgebraicResult::None => AlgebraicStatus::None,
293 AlgebraicResult::Element(_) => AlgebraicStatus::Element,
294 AlgebraicResult::Identity(mask) => {
295 if mask & SELF_IDENT > 0 {
296 AlgebraicStatus::Identity
297 } else {
298 AlgebraicStatus::Element
299 }
300 }
301 }
302 }
303}
304
305impl<V> AlgebraicResult<Option<V>> {
306 #[inline]
309 pub fn flatten(self) -> AlgebraicResult<V> {
310 match self {
311 Self::Element(v) => {
312 match v {
313 Some(v) => AlgebraicResult::Element(v),
314 None => AlgebraicResult::None
315 }
316 },
317 Self::None => AlgebraicResult::None,
318 Self::Identity(mask) => AlgebraicResult::Identity(mask),
319 }
320 }
321}
322
323#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
339pub enum AlgebraicStatus {
340 #[default]
342 Element,
343 Identity,
345 None,
347}
348
349impl AlgebraicStatus {
350 #[inline]
352 pub fn is_none(&self) -> bool {
353 matches!(self, Self::None)
354 }
355 #[inline]
357 pub fn is_identity(&self) -> bool {
358 matches!(self, Self::Identity)
359 }
360 #[inline]
362 pub fn is_element(&self) -> bool {
363 matches!(self, Self::Element)
364 }
365 #[inline]
374 pub fn merge(self, b: Self, self_none: bool, b_none: bool) -> AlgebraicStatus {
375 match self {
376 Self::None => match b {
377 Self::None => Self::None,
378 Self::Element => Self::Element,
379 Self::Identity => if self_none {
380 Self::Identity
381 } else {
382 Self::Element
383 },
384 },
385 Self::Identity => match b {
386 Self::Element => Self::Element,
387 Self::Identity => Self::Identity,
388 Self::None => if b_none {
389 Self::Identity
390 } else {
391 Self::Element
392 },
393 },
394 Self::Element => Self::Element
395 }
396 }
397}
398
399impl<V> From<FatAlgebraicResult<V>> for AlgebraicResult<V> {
400 #[inline]
401 fn from(src: FatAlgebraicResult<V>) -> Self {
402 if src.identity_mask > 0 {
403 AlgebraicResult::Identity(src.identity_mask)
404 } else {
405 match src.element {
406 Some(element) => AlgebraicResult::Element(element),
407 None => AlgebraicResult::None
408 }
409 }
410 }
411}
412
413#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
415pub(crate) struct FatAlgebraicResult<V> {
416 pub identity_mask: u64,
418 pub element: Option<V>,
421}
422
423impl<V> FatAlgebraicResult<V> {
424 #[inline(always)]
425 pub(crate) const fn new(identity_mask: u64, element: Option<V>) -> Self {
426 Self {identity_mask, element}
427 }
428 #[inline]
431 pub(crate) fn from_binary_op_result(result: AlgebraicResult<V>, a: &V, b: &V) -> Self
432 where V: Clone
433 {
434 match result {
435 AlgebraicResult::None => FatAlgebraicResult::none(),
436 AlgebraicResult::Element(v) => FatAlgebraicResult::element(v),
437 AlgebraicResult::Identity(mask) => {
438 debug_assert!(mask <= (SELF_IDENT | COUNTER_IDENT));
439 if mask & SELF_IDENT > 0 {
440 FatAlgebraicResult::new(mask, Some(a.clone()))
441 } else {
442 debug_assert_eq!(mask, COUNTER_IDENT);
443 FatAlgebraicResult::new(mask, Some(b.clone()))
444 }
445 }
446 }
447 }
448 #[inline]
450 pub fn map<U, F>(self, f: F) -> FatAlgebraicResult<U>
451 where F: FnOnce(V) -> U,
452 {
453 FatAlgebraicResult::<U> {
454 identity_mask: self.identity_mask,
455 element: self.element.map(f)
456 }
457 }
458 #[inline(always)]
460 pub(crate) const fn none() -> Self {
461 Self {identity_mask: 0, element: None}
462 }
463 #[inline(always)]
465 pub(crate) fn element(e: V) -> Self {
466 Self {identity_mask: 0, element: Some(e)}
467 }
468 pub fn join(self, arg: &V, arg_idx: usize) -> Self where V: Lattice + Clone {
509 match self.element {
510 None => {
511 Self::new(self.identity_mask | 1 << arg_idx, Some(arg.clone()))
512 },
513 Some(self_element) => match self_element.pjoin(&arg) {
514 AlgebraicResult::None => Self::none(),
515 AlgebraicResult::Element(e) => Self::element(e),
516 AlgebraicResult::Identity(mask) => {
517 if mask & SELF_IDENT > 0 {
518 let new_mask = self.identity_mask | ((mask & COUNTER_IDENT) << (arg_idx-1));
519 Self::new(new_mask, Some(self_element))
520 } else {
521 debug_assert!(mask & COUNTER_IDENT > 0);
522 let new_mask = (mask & COUNTER_IDENT) << (arg_idx-1);
523 Self::new(new_mask, Some(arg.clone()))
524 }
525 }
526 }
527 }
528 }
529}
530
531pub trait Lattice {
533 fn pjoin(&self, other: &Self) -> AlgebraicResult<Self> where Self: Sized;
536
537 fn join_into(&mut self, other: Self) -> AlgebraicStatus where Self: Sized {
540 let result = self.pjoin(&other);
541 in_place_default_impl(result, self, other, |_s| {}, |e| e)
545 }
546
547 fn pmeet(&self, other: &Self) -> AlgebraicResult<Self> where Self: Sized;
549
550 fn join_all<S: AsRef<Self>, Args: AsRef<[S]>>(xs: Args) -> AlgebraicResult<Self> where Self: Sized + Clone {
555 let mut iter = xs.as_ref().into_iter().enumerate();
556 let mut result = match iter.next() {
557 None => return AlgebraicResult::None,
558 Some((_, first)) => FatAlgebraicResult::new(SELF_IDENT, Some(first.as_ref().clone())),
559 };
560 for (i, next) in iter {
561 result = result.join(next.as_ref(), i);
562 }
563 result.into()
564 }
565}
566
567fn in_place_default_impl<SelfT, OtherT, ConvertF, DefaultF>(result: AlgebraicResult<SelfT>, self_ref: &mut SelfT, other: OtherT, default_f: DefaultF, convert_f: ConvertF) -> AlgebraicStatus
569 where
570 DefaultF: FnOnce(&mut SelfT),
571 ConvertF: Fn(OtherT) -> SelfT
572{
573 match result {
574 AlgebraicResult::None => {
575 default_f(self_ref);
576 AlgebraicStatus::None
577 },
578 AlgebraicResult::Element(v) => {
579 *self_ref = v;
580 AlgebraicStatus::Element
581 },
582 AlgebraicResult::Identity(mask) => {
583 if mask & SELF_IDENT > 0 {
584 AlgebraicStatus::Identity
585 } else {
586 *self_ref = convert_f(other);
587 AlgebraicStatus::Element
588 }
589 },
590 }
591}
592
593pub trait LatticeRef {
596 type T;
597 fn pjoin(&self, other: &Self) -> AlgebraicResult<Self::T>;
598 fn pmeet(&self, other: &Self) -> AlgebraicResult<Self::T>;
599}
600
601pub trait DistributiveLattice {
603 fn psubtract(&self, other: &Self) -> AlgebraicResult<Self> where Self: Sized;
605
606 }
608
609pub trait DistributiveLatticeRef {
611 type T;
613
614 fn psubtract(&self, other: &Self) -> AlgebraicResult<Self::T>;
617}
618
619pub(crate) trait Quantale {
629 fn prestrict(&self, other: &Self) -> AlgebraicResult<Self> where Self: Sized;
631}
632
633pub(crate) trait HeteroLattice<OtherT> {
636 fn pjoin(&self, other: &OtherT) -> AlgebraicResult<Self> where Self: Sized;
637 fn join_into(&mut self, other: OtherT) -> AlgebraicStatus where Self: Sized {
638 let result = self.pjoin(&other);
639 in_place_default_impl(result, self, other, |_s| {}, |e| Self::convert(e))
641 }
642 fn pmeet(&self, other: &OtherT) -> AlgebraicResult<Self> where Self: Sized;
643 fn convert(other: OtherT) -> Self;
645}
646
647pub(crate) trait HeteroDistributiveLattice<OtherT> {
650 fn psubtract(&self, other: &OtherT) -> AlgebraicResult<Self> where Self: Sized;
651}
652
653pub(crate) trait HeteroQuantale<OtherT> {
655 fn prestrict(&self, other: &OtherT) -> AlgebraicResult<Self> where Self: Sized;
656}
657
658impl<V: Lattice + Clone> Lattice for Option<V> {
666 fn pjoin(&self, other: &Option<V>) -> AlgebraicResult<Self> {
667 match self {
668 None => match other {
669 None => { AlgebraicResult::None }
670 Some(_) => { AlgebraicResult::Identity(COUNTER_IDENT) }
671 },
672 Some(l) => match other {
673 None => { AlgebraicResult::Identity(SELF_IDENT) }
674 Some(r) => { l.pjoin(r).map(|result| Some(result)) }
675 }
676 }
677 }
678 fn join_into(&mut self, other: Self) -> AlgebraicStatus {
679 match self {
680 None => { match other {
681 None => AlgebraicStatus::None,
682 Some(r) => {
683 *self = Some(r);
684 AlgebraicStatus::Element
685 }
686 } }
687 Some(l) => match other {
688 None => AlgebraicStatus::Identity,
689 Some(r) => {
690 l.join_into(r)
691 }
692 }
693 }
694 }
695 fn pmeet(&self, other: &Option<V>) -> AlgebraicResult<Option<V>> {
696 match self {
697 None => { AlgebraicResult::None }
698 Some(l) => {
699 match other {
700 None => { AlgebraicResult::None }
701 Some(r) => l.pmeet(r).map(|result| Some(result))
702 }
703 }
704 }
705 }
706}
707
708impl<V: DistributiveLattice + Clone> DistributiveLattice for Option<V> {
709 fn psubtract(&self, other: &Self) -> AlgebraicResult<Self> {
710 match self {
711 None => { AlgebraicResult::None }
712 Some(s) => {
713 match other {
714 None => { AlgebraicResult::Identity(SELF_IDENT) }
715 Some(o) => { s.psubtract(o).map(|v| Some(v)) }
716 }
717 }
718 }
719 }
720}
721
722#[test]
723fn option_subtract_test() {
724 assert_eq!(Some(()).psubtract(&Some(())), AlgebraicResult::None);
725 assert_eq!(Some(()).psubtract(&None), AlgebraicResult::Identity(SELF_IDENT));
726 assert_eq!(Some(Some(())).psubtract(&Some(Some(()))), AlgebraicResult::None);
727 assert_eq!(Some(Some(())).psubtract(&None), AlgebraicResult::Identity(SELF_IDENT));
728 assert_eq!(Some(Some(())).psubtract(&Some(None)), AlgebraicResult::Identity(SELF_IDENT));
729 assert_eq!(Some(Some(Some(()))).psubtract(&Some(Some(None))), AlgebraicResult::Identity(SELF_IDENT));
730 assert_eq!(Some(Some(Some(()))).psubtract(&Some(Some(Some(())))), AlgebraicResult::None);
731}
732
733impl<V: Lattice + Clone> LatticeRef for Option<&V> {
737 type T = Option<V>;
738 fn pjoin(&self, other: &Self) -> AlgebraicResult<Self::T> {
739 match self {
740 None => { match other {
741 None => { AlgebraicResult::None }
742 Some(_) => { AlgebraicResult::Identity(COUNTER_IDENT) }
743 } }
744 Some(l) => match other {
745 None => { AlgebraicResult::Identity(SELF_IDENT) }
746 Some(r) => { l.pjoin(r).map(|result| Some(result)) }
747 }
748 }
749 }
750 fn pmeet(&self, other: &Option<&V>) -> AlgebraicResult<Option<V>> {
751 match self {
752 None => { AlgebraicResult::None }
753 Some(l) => {
754 match other {
755 None => { AlgebraicResult::None }
756 Some(r) => l.pmeet(r).map(|result| Some(result))
757 }
758 }
759 }
760 }
761}
762
763impl<V: DistributiveLattice + Clone> DistributiveLatticeRef for Option<&V> {
764 type T = Option<V>;
765 fn psubtract(&self, other: &Self) -> AlgebraicResult<Self::T> {
766 match self {
767 None => { AlgebraicResult::None }
768 Some(s) => {
769 match other {
770 None => { AlgebraicResult::Identity(SELF_IDENT) }
771 Some(o) => { s.psubtract(o).map(|v| Some(v)) }
772 }
773 }
774 }
775 }
776}
777
778impl <V: Lattice> Lattice for Box<V> {
782 fn pjoin(&self, other: &Self) -> AlgebraicResult<Self> {
783 self.as_ref().pjoin(other.as_ref()).map(|result| Box::new(result))
784 }
785 fn pmeet(&self, other: &Self) -> AlgebraicResult<Self> {
786 self.as_ref().pmeet(other.as_ref()).map(|result| Box::new(result))
787 }
788}
789
790impl<V: DistributiveLattice> DistributiveLattice for Box<V> {
791 fn psubtract(&self, other: &Self) -> AlgebraicResult<Self> {
792 self.as_ref().psubtract(other.as_ref()).map(|result| Box::new(result))
793 }
794}
795
796impl <V: Lattice> LatticeRef for &V {
800 type T = V;
801 fn pjoin(&self, other: &Self) -> AlgebraicResult<Self::T> {
802 (**self).pjoin(other)
803 }
804 fn pmeet(&self, other: &Self) -> AlgebraicResult<Self::T> {
805 (**self).pmeet(other)
806 }
807}
808
809impl<V: DistributiveLattice> DistributiveLatticeRef for &V {
810 type T = V;
811 fn psubtract(&self, other: &Self) -> AlgebraicResult<Self::T> {
812 (**self).psubtract(other)
813 }
814}
815
816impl DistributiveLattice for () {
820 fn psubtract(&self, _other: &Self) -> AlgebraicResult<Self> where Self: Sized {
821 AlgebraicResult::None
822 }
823}
824
825impl Lattice for () {
826 fn pjoin(&self, _other: &Self) -> AlgebraicResult<Self> { AlgebraicResult::Identity(SELF_IDENT | COUNTER_IDENT) }
827 fn pmeet(&self, _other: &Self) -> AlgebraicResult<Self> { AlgebraicResult::Identity(SELF_IDENT | COUNTER_IDENT) }
828}
829
830impl Lattice for usize {
832 fn pjoin(&self, _other: &usize) -> AlgebraicResult<usize> { AlgebraicResult::Identity(SELF_IDENT) }
833 fn pmeet(&self, _other: &usize) -> AlgebraicResult<usize> { AlgebraicResult::Identity(SELF_IDENT) }
834}
835
836impl Lattice for u64 {
838 fn pjoin(&self, _other: &u64) -> AlgebraicResult<u64> { AlgebraicResult::Identity(SELF_IDENT) }
839 fn pmeet(&self, _other: &u64) -> AlgebraicResult<u64> { AlgebraicResult::Identity(SELF_IDENT) }
840}
841
842impl DistributiveLattice for u64 {
844 fn psubtract(&self, other: &Self) -> AlgebraicResult<Self> where Self: Sized {
845 if self == other { AlgebraicResult::None }
846 else { AlgebraicResult::Element(*self) }
847 }
848}
849
850impl Lattice for u32 {
852 fn pjoin(&self, _other: &u32) -> AlgebraicResult<u32> { AlgebraicResult::Identity(SELF_IDENT) }
853 fn pmeet(&self, _other: &u32) -> AlgebraicResult<u32> { AlgebraicResult::Identity(SELF_IDENT) }
854}
855
856impl Lattice for u16 {
858 fn pjoin(&self, _other: &u16) -> AlgebraicResult<u16> { AlgebraicResult::Identity(SELF_IDENT) }
859 fn pmeet(&self, _other: &u16) -> AlgebraicResult<u16> { AlgebraicResult::Identity(SELF_IDENT) }
860}
861
862impl DistributiveLattice for u16 {
864 fn psubtract(&self, other: &Self) -> AlgebraicResult<Self> {
865 if self == other { AlgebraicResult::None }
866 else { AlgebraicResult::Element(*self) }
867 }
868}
869
870impl Lattice for u8 {
872 fn pjoin(&self, _other: &u8) -> AlgebraicResult<u8> { AlgebraicResult::Identity(SELF_IDENT) }
873 fn pmeet(&self, _other: &u8) -> AlgebraicResult<u8> { AlgebraicResult::Identity(SELF_IDENT) }
874}
875
876impl DistributiveLattice for bool {
882 fn psubtract(&self, other: &bool) -> AlgebraicResult<Self> {
883 if *self == *other {
884 AlgebraicResult::None
885 } else {
886 AlgebraicResult::Identity(SELF_IDENT)
887 }
888 }
889}
890
891impl Lattice for bool {
892 fn pjoin(&self, other: &bool) -> AlgebraicResult<bool> {
893 if !*self && *other {
894 AlgebraicResult::Identity(COUNTER_IDENT) } else {
896 AlgebraicResult::Identity(SELF_IDENT)
897 }
898 }
899 fn pmeet(&self, other: &bool) -> AlgebraicResult<bool> {
900 if *self && !*other {
901 AlgebraicResult::Identity(COUNTER_IDENT) } else {
903 AlgebraicResult::Identity(SELF_IDENT)
904 }
905 }
906}
907
908pub trait SetLattice {
919 type K: Clone + Eq;
921
922 type V: Clone;
924
925 type Iter<'a>: Iterator<Item=(&'a Self::K, &'a Self::V)> where Self: 'a, Self::V: 'a, Self::K: 'a;
927
928 fn with_capacity(capacity: usize) -> Self;
930
931 fn len(&self) -> usize;
933
934 fn is_empty(&self) -> bool;
936
937 fn contains_key(&self, key: &Self::K) -> bool;
939
940 fn insert(&mut self, key: Self::K, val: Self::V);
942
943 fn remove(&mut self, key: &Self::K);
945
946 fn get(&self, key: &Self::K) -> Option<&Self::V>;
948
949 fn replace(&mut self, key: &Self::K, val: Self::V);
951
952 fn iter<'a>(&'a self) -> Self::Iter<'a>;
954
955 fn shrink_to_fit(&mut self);
957}
958
959#[macro_export]
961macro_rules! set_lattice {
962 ( $type_ident:ident $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? ) => {
963 impl $(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::ring::Lattice for $type_ident $(< $( $lt ),+ >)? where Self: $crate::ring::SetLattice, <Self as $crate::ring::SetLattice>::V: $crate::ring::Lattice {
964 fn pjoin(&self, other: &Self) -> $crate::ring::AlgebraicResult<Self> {
965 let self_len = $crate::ring::SetLattice::len(self);
966 let other_len = $crate::ring::SetLattice::len(other);
967 let mut result = <Self as $crate::ring::SetLattice>::with_capacity(self_len.max(other_len));
968 let mut is_ident = self_len >= other_len;
969 let mut is_counter_ident = self_len <= other_len;
970 for (key, self_val) in $crate::ring::SetLattice::iter(self) {
971 if let Some(other_val) = $crate::ring::SetLattice::get(other, key) {
972 let inner_result = self_val.pjoin(other_val);
974 $crate::ring::set_lattice_update_ident_flags_with_result(
975 &mut result, inner_result, key, self_val, other_val, &mut is_ident, &mut is_counter_ident
976 );
977 } else {
978 $crate::ring::SetLattice::insert(&mut result, key.clone(), self_val.clone());
980 is_counter_ident = false;
981 }
982 }
983 for (key, value) in SetLattice::iter(other) {
984 if !$crate::ring::SetLattice::contains_key(self, key) {
985 $crate::ring::SetLattice::insert(&mut result, key.clone(), value.clone());
987 is_ident = false;
988 }
989 }
990 $crate::ring::set_lattice_integrate_into_result(result, is_ident, is_counter_ident, self_len, other_len)
991 }
992 fn pmeet(&self, other: &Self) -> $crate::ring::AlgebraicResult<Self> {
993 let mut result = <Self as $crate::ring::SetLattice>::with_capacity(0);
994 let mut is_ident = true;
995 let mut is_counter_ident = true;
996 let (smaller, larger, switch) = if $crate::ring::SetLattice::len(self) < $crate::ring::SetLattice::len(other) {
997 (self, other, false)
998 } else {
999 (other, self, true)
1000 };
1001 for (key, self_val) in $crate::ring::SetLattice::iter(smaller) {
1002 if let Some(other_val) = $crate::ring::SetLattice::get(larger, key) {
1003 let inner_result = self_val.pmeet(other_val);
1004 $crate::ring::set_lattice_update_ident_flags_with_result(
1005 &mut result, inner_result, key, self_val, other_val, &mut is_ident, &mut is_counter_ident
1006 );
1007 } else {
1008 is_ident = false;
1009 }
1010 }
1011 if switch {
1012 core::mem::swap(&mut is_ident, &mut is_counter_ident);
1013 }
1014 $crate::ring::set_lattice_integrate_into_result(result, is_ident, is_counter_ident, self.len(), other.len())
1015 }
1016 }
1017 }
1018}
1019
1020#[inline]
1022#[doc(hidden)]
1023pub fn set_lattice_update_ident_flags_with_result<S: SetLattice>(
1024 result_set: &mut S,
1025 result: AlgebraicResult<S::V>,
1026 key: &S::K,
1027 self_val: &S::V,
1028 other_val: &S::V,
1029 is_ident: &mut bool,
1030 is_counter_ident: &mut bool
1031) {
1032 match result {
1033 AlgebraicResult::None => {
1034 *is_ident = false;
1035 *is_counter_ident = false;
1036 },
1037 AlgebraicResult::Element(new_val) => {
1038 *is_ident = false;
1039 *is_counter_ident = false;
1040 result_set.insert(key.clone(), new_val);
1041 },
1042 AlgebraicResult::Identity(mask) => {
1043 if mask & SELF_IDENT > 0 {
1044 result_set.insert(key.clone(), self_val.clone());
1045 } else {
1046 *is_ident = false;
1047 }
1048 if mask & COUNTER_IDENT > 0 {
1049 if mask & SELF_IDENT == 0 {
1050 result_set.insert(key.clone(), other_val.clone());
1051 }
1052 } else {
1053 *is_counter_ident = false;
1054 }
1055 }
1056 }
1057}
1058
1059#[inline]
1061#[doc(hidden)]
1062pub fn set_lattice_integrate_into_result<S: SetLattice>(
1063 result_set: S,
1064 is_ident: bool,
1065 is_counter_ident: bool,
1066 self_set_len: usize,
1067 other_set_len: usize,
1068) -> AlgebraicResult<S> {
1069 let result_len = result_set.len();
1070 if result_len == 0 {
1071 AlgebraicResult::None
1072 } else {
1073 let mut ident_mask = 0;
1074 if is_ident && self_set_len == result_len {
1075 ident_mask |= SELF_IDENT;
1076 }
1077 if is_counter_ident && other_set_len == result_len {
1078 ident_mask |= COUNTER_IDENT;
1079 }
1080 if ident_mask > 0 {
1081 AlgebraicResult::Identity(ident_mask)
1082 } else {
1083 AlgebraicResult::Element(result_set)
1084 }
1085 }
1086}
1087
1088#[macro_export]
1090macro_rules! set_dist_lattice {
1091 ( $type_ident:ident $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? ) => {
1092 impl $(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::ring::DistributiveLattice for $type_ident $(< $( $lt ),+ >)? where Self: $crate::ring::SetLattice + Clone, <Self as $crate::ring::SetLattice>::V: $crate::ring::DistributiveLattice {
1093 fn psubtract(&self, other: &Self) -> $crate::ring::AlgebraicResult<Self> {
1094 let mut is_ident = true;
1095 let mut result = self.clone();
1096 if $crate::ring::SetLattice::len(self) > $crate::ring::SetLattice::len(other) {
1098 for (key, other_val) in $crate::ring::SetLattice::iter(other) {
1099 if let Some(self_val) = $crate::ring::SetLattice::get(self, key) {
1100 set_lattice_subtract_element(&mut result, key, self_val, other_val, &mut is_ident)
1101 }
1102 }
1103 } else {
1104 for (key, self_val) in $crate::ring::SetLattice::iter(self) {
1105 if let Some(other_val) = $crate::ring::SetLattice::get(other, key) {
1106 set_lattice_subtract_element(&mut result, key, self_val, other_val, &mut is_ident)
1107 }
1108 }
1109 }
1110 if $crate::ring::SetLattice::len(&result) == 0 {
1111 $crate::ring::AlgebraicResult::None
1112 } else if is_ident {
1113 $crate::ring::AlgebraicResult::Identity(SELF_IDENT)
1114 } else {
1115 $crate::ring::SetLattice::shrink_to_fit(&mut result);
1116 $crate::ring::AlgebraicResult::Element(result)
1117 }
1118 }
1119 }
1120 }
1121}
1122
1123#[inline]
1125fn set_lattice_subtract_element<S: SetLattice>(
1126 result_set: &mut S,
1127 key: &S::K,
1128 self_val: &S::V,
1129 other_val: &S::V,
1130 is_ident: &mut bool,
1131) where S::V: DistributiveLattice {
1132 match self_val.psubtract(other_val) {
1133 AlgebraicResult::Element(new_val) => {
1134 SetLattice::replace(result_set, key, new_val);
1135 *is_ident = false;
1136 },
1137 AlgebraicResult::Identity(mask) => {
1138 debug_assert_eq!(mask, SELF_IDENT);
1139 },
1140 AlgebraicResult::None => {
1141 SetLattice::remove(result_set, key);
1142 *is_ident = false;
1143 }
1144 }
1145}
1146
1147impl<K: Clone + Eq + Hash, V: Clone + Lattice> SetLattice for HashMap<K, V> {
1148 type K = K;
1149 type V = V;
1150 type Iter<'a> = std::collections::hash_map::Iter<'a, K, V> where K: 'a, V: 'a;
1151 fn with_capacity(capacity: usize) -> Self { Self::with_capacity(capacity) }
1152 fn len(&self) -> usize { self.len() }
1153 fn is_empty(&self) -> bool { self.is_empty() }
1154 fn contains_key(&self, key: &Self::K) -> bool { self.contains_key(key) }
1155 fn insert(&mut self, key: Self::K, val: Self::V) { self.insert(key, val); }
1156 fn get(&self, key: &Self::K) -> Option<&Self::V> { self.get(key) }
1157 fn replace(&mut self, key: &Self::K, val: Self::V) { *self.get_mut(key).unwrap() = val }
1158 fn remove(&mut self, key: &Self::K) { self.remove(key); }
1159 fn iter<'a>(&'a self) -> Self::Iter<'a> { self.iter() }
1160 fn shrink_to_fit(&mut self) { self.shrink_to_fit(); }
1161}
1162
1163set_lattice!(HashMap<K, V>);
1164set_dist_lattice!(HashMap<K, V>);
1165
1166impl<K: Clone + Eq + Hash> SetLattice for HashSet<K> {
1167 type K = K;
1168 type V = ();
1169 type Iter<'a> = HashSetIterWrapper<'a, K> where K: 'a;
1170 fn with_capacity(capacity: usize) -> Self { Self::with_capacity(capacity) }
1171 fn len(&self) -> usize { self.len() }
1172 fn is_empty(&self) -> bool { self.is_empty() }
1173 fn contains_key(&self, key: &Self::K) -> bool { self.contains(key) }
1174 fn insert(&mut self, key: Self::K, _val: Self::V) { self.insert(key); }
1175 fn get(&self, key: &Self::K) -> Option<&Self::V> { self.get(key).map(|_| &()) }
1176 fn replace(&mut self, key: &Self::K, _val: Self::V) { debug_assert!(self.contains(key)); }
1177 fn remove(&mut self, key: &Self::K) { self.remove(key); }
1178 fn iter<'a>(&'a self) -> Self::Iter<'a> { HashSetIterWrapper(self.iter()) }
1179 fn shrink_to_fit(&mut self) { self.shrink_to_fit(); }
1180}
1181
1182pub struct HashSetIterWrapper<'a, K> (std::collections::hash_set::Iter<'a, K>);
1183
1184impl<'a, K> Iterator for HashSetIterWrapper<'a, K> {
1185 type Item = (&'a K, &'a());
1186 fn next(&mut self) -> Option<(&'a K, &'a())> {
1187 self.0.next().map(|key| (key, &()))
1188 }
1189}
1190
1191set_lattice!(HashSet<K>);
1192set_dist_lattice!(HashSet<K>);
1193
1194#[cfg(test)]
1195mod tests {
1196 use std::collections::{HashSet, HashMap};
1197 use crate::ring::Lattice;
1198 use super::{AlgebraicResult, SetLattice, SELF_IDENT, COUNTER_IDENT};
1199
1200 #[test]
1201 fn set_lattice_join_test1() {
1202 let mut a = HashSet::new();
1203 let mut b = HashSet::new();
1204
1205 let joined_result = a.pjoin(&b);
1207 assert_eq!(joined_result, AlgebraicResult::None);
1208
1209 a.insert("A");
1211 b.insert("B");
1212 let joined_result = a.pjoin(&b);
1213 assert!(joined_result.is_element());
1214 let joined = joined_result.unwrap([&a, &b]);
1215 assert_eq!(joined.len(), 2);
1216 assert!(joined.get("A").is_some());
1217 assert!(joined.get("B").is_some());
1218
1219 a.insert("C");
1221 let joined_result = a.pjoin(&b);
1222 assert!(joined_result.is_element());
1223 let joined = joined_result.unwrap([&a, &b]);
1224 assert_eq!(joined.len(), 3);
1225
1226 b.insert("D");
1228 b.insert("F");
1229 b.insert("H");
1230 let joined_result = a.pjoin(&b);
1231 assert!(joined_result.is_element());
1232 let joined = joined_result.unwrap([&a, &b]);
1233 assert_eq!(joined.len(), 6);
1234
1235 let joined_result = joined.pjoin(&b);
1237 assert_eq!(joined_result, AlgebraicResult::Identity(SELF_IDENT));
1238
1239 let joined_result = b.pjoin(&joined);
1241 assert_eq!(joined_result, AlgebraicResult::Identity(COUNTER_IDENT));
1242
1243 let joined_result = joined.pjoin(&joined);
1245 assert_eq!(joined_result, AlgebraicResult::Identity(SELF_IDENT | COUNTER_IDENT));
1246 }
1247
1248 #[test]
1249 fn set_lattice_meet_test1() {
1250 let mut a = HashSet::new();
1251 let mut b = HashSet::new();
1252
1253 a.insert("A");
1255 b.insert("B");
1256 let meet_result = a.pmeet(&b);
1257 assert_eq!(meet_result, AlgebraicResult::None);
1258
1259 a.insert("A");
1261 a.insert("C");
1262 b.insert("B");
1263 b.insert("C");
1264 let meet_result = a.pmeet(&b);
1265 assert!(meet_result.is_element());
1266 let meet = meet_result.unwrap([&a, &b]);
1267 assert_eq!(meet.len(), 1);
1268 assert!(meet.get("A").is_none());
1269 assert!(meet.get("B").is_none());
1270 assert!(meet.get("C").is_some());
1271
1272 a.insert("D");
1274 let meet_result = a.pmeet(&b);
1275 assert!(meet_result.is_element());
1276 let meet = meet_result.unwrap([&a, &b]);
1277 assert_eq!(meet.len(), 1);
1278
1279 b.insert("D");
1281 b.insert("E");
1282 b.insert("F");
1283 let meet_result = a.pmeet(&b);
1284 assert!(meet_result.is_element());
1285 let meet = meet_result.unwrap([&a, &b]);
1286 assert_eq!(meet.len(), 2);
1287
1288 let meet_result = meet.pmeet(&b);
1290 assert_eq!(meet_result, AlgebraicResult::Identity(SELF_IDENT));
1291
1292 let meet_result = b.pmeet(&meet);
1294 assert_eq!(meet_result, AlgebraicResult::Identity(COUNTER_IDENT));
1295
1296 let meet_result = meet.pmeet(&meet);
1298 assert_eq!(meet_result, AlgebraicResult::Identity(SELF_IDENT | COUNTER_IDENT));
1299 }
1300
1301 #[derive(Clone, Debug)]
1303 struct Map<'a>(HashMap::<&'a str, HashMap<&'a str, ()>>);impl<'a> SetLattice for Map<'a> {
1305 type K = &'a str;
1306 type V = HashMap<&'a str, ()>; type Iter<'it> = std::collections::hash_map::Iter<'it, Self::K, Self::V> where Self: 'it, Self::K: 'it, Self::V: 'it;
1308 fn with_capacity(capacity: usize) -> Self { Map(HashMap::with_capacity(capacity)) }
1309 fn len(&self) -> usize { self.0.len() }
1310 fn is_empty(&self) -> bool { self.0.is_empty() }
1311 fn contains_key(&self, key: &Self::K) -> bool { self.0.contains_key(key) }
1312 fn insert(&mut self, key: Self::K, val: Self::V) { self.0.insert(key, val); }
1313 fn get(&self, key: &Self::K) -> Option<&Self::V> { self.0.get(key) }
1314 fn replace(&mut self, key: &Self::K, val: Self::V) { self.0.replace(key, val) }
1315 fn remove(&mut self, key: &Self::K) { self.0.remove(key); }
1316 fn iter<'it>(&'it self) -> Self::Iter<'it> { self.0.iter() }
1317 fn shrink_to_fit(&mut self) { self.0.shrink_to_fit(); }
1318 }
1319 set_lattice!(Map<'a>);
1320
1321 #[test]
1322 fn set_lattice_join_test2() {
1327 let mut a = Map::with_capacity(1);
1328 let mut b = Map::with_capacity(1);
1329
1330 let mut inner_map_1 = HashMap::with_capacity(1);
1332 inner_map_1.insert("1", ());
1333 a.0.insert("A", inner_map_1.clone());
1334 b.0.insert("B", inner_map_1);
1335 let joined_result = a.pjoin(&b);
1337 assert!(joined_result.is_element());
1338 let joined = joined_result.unwrap([&a, &b]);
1339 assert_eq!(joined.len(), 2);
1340 assert!(joined.get(&"A").is_some());
1341 assert!(joined.get(&"B").is_some());
1342 assert!(joined.get(&"C").is_none()); let mut inner_map_2 = HashMap::with_capacity(1);
1346 inner_map_2.insert("2", ());
1347 b.0.remove("B");
1348 b.0.insert("A", inner_map_2);
1349 let joined_result = a.pjoin(&b);
1350 assert!(joined_result.is_element());
1351 let joined = joined_result.unwrap([&a, &b]);
1352 assert_eq!(joined.len(), 1);
1353 let joined_inner = joined.get(&"A").unwrap();
1354 assert_eq!(joined_inner.len(), 2);
1355 assert!(joined_inner.get(&"1").is_some());
1356 assert!(joined_inner.get(&"2").is_some());
1357
1358 let joined_result = joined.pjoin(&a);
1360 assert_eq!(joined_result.identity_mask().unwrap(), SELF_IDENT);
1361 let joined_result = b.pjoin(&joined);
1362 assert_eq!(joined_result.identity_mask().unwrap(), COUNTER_IDENT);
1363 }
1364
1365 #[test]
1366 fn set_lattice_meet_test2() {
1368 let mut a = Map::with_capacity(1);
1369 let mut b = Map::with_capacity(1);
1370
1371 let mut inner_map_a = HashMap::new();
1372 inner_map_a.insert("a", ());
1373 let mut inner_map_b = HashMap::new();
1374 inner_map_b.insert("b", ());
1375 let mut inner_map_c = HashMap::new();
1376 inner_map_c.insert("c", ());
1377
1378 a.0.insert("A", inner_map_a.clone());
1380 a.0.insert("C", inner_map_c.clone());
1381 b.0.insert("B", inner_map_b.clone());
1382 b.0.insert("C", inner_map_c.clone());
1383 let meet_result = a.pmeet(&b);
1384 assert!(meet_result.is_element());
1385 let meet = meet_result.unwrap([&a, &b]);
1386 assert_eq!(meet.len(), 1);
1387 assert!(meet.get(&"A").is_none());
1388 assert!(meet.get(&"B").is_none());
1389 assert!(meet.get(&"C").is_some());
1390
1391 let mut inner_map_1 = HashMap::with_capacity(1);
1393 inner_map_1.insert("1", ());
1394 a.0.insert("A", inner_map_1);
1395 let mut inner_map_2 = HashMap::with_capacity(1);
1396 inner_map_2.insert("2", ());
1397 b.0.remove("B");
1398 b.0.remove("C");
1399 b.0.insert("A", inner_map_2.clone());
1400 let meet_result = a.pmeet(&b);
1401 assert!(meet_result.is_none());
1402
1403 inner_map_2.insert("1", ());
1405 b.0.insert("A", inner_map_2);
1406 let meet_result = a.pmeet(&b);
1407 assert!(meet_result.is_element());
1408 let meet = meet_result.unwrap([&a, &b]);
1409 assert_eq!(meet.len(), 1);
1410 let meet_inner = meet.get(&"A").unwrap();
1411 assert_eq!(meet_inner.len(), 1);
1412 assert!(meet_inner.get(&"1").is_some());
1413 assert!(meet_inner.get(&"2").is_none());
1414
1415 let meet_result = meet.pmeet(&a);
1417 assert_eq!(meet_result.identity_mask().unwrap(), SELF_IDENT);
1418 let meet_result = b.pmeet(&meet);
1419 assert_eq!(meet_result.identity_mask().unwrap(), COUNTER_IDENT);
1420 }
1421}
1422
1423