diff --git a/btypes_lazy/src/main/rust/bmachine/Cargo.toml b/btypes_lazy/src/main/rust/bmachine/Cargo.toml deleted file mode 100644 index 1f4c46e38bde5648b94b4d5e195236ccd4c1d26d..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/bmachine/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "bmachine" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -rand = "0.8.3" -im = "15.0.0" -threadpool = "1.8.1" -derivative = "2.2.0" -dashmap = "5.1.0" -btypes = { path = "../btypes" } - -[profile.release] -opt-level = 3 - -[profile.dev] -opt-level = 0 diff --git a/btypes_lazy/src/main/rust/btypes/Cargo.toml b/btypes_lazy/src/main/rust/btypes/Cargo.toml deleted file mode 100644 index f1c1a2a93fe25128e266521f7468465569ade379..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "btypes" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -rand = "0.8.3" -im = "15.0.0" -lazy_static = "1.4.0" \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/bboolean.rs b/btypes_lazy/src/main/rust/btypes/src/bboolean.rs deleted file mode 100644 index b1188ebb86908343e28a29db304c0f18e0e8b531..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/bboolean.rs +++ /dev/null @@ -1,40 +0,0 @@ -use crate::bobject::BObject; - -pub type BBoolean = bool; - -pub trait IntoBool { - #![allow(non_snake_case)] - fn booleanValue(&self) -> bool; -} - -pub trait BBooleanT: BObject + IntoBool + Copy { - fn new(val: bool) -> Self; - fn or(&self, other: &Self) -> Self; - fn xor(&self, other: &Self) -> Self; - fn and(&self, other: &Self) -> Self; - fn not(&self) -> Self; - fn implies(&self, other: &Self) -> Self; - fn equivalent(&self, other: &Self) -> Self; - fn equal(&self, other: &Self) -> Self; - fn unequal(&self, other: &Self) -> Self; -} - -impl IntoBool for bool { - fn booleanValue(&self) -> bool { - return *self; - } -} - -impl BObject for bool {} - -impl BBooleanT for bool { - fn new(val: bool) -> Self { val } - fn or(&self, other: &Self) -> Self { *self || *other } - fn xor(&self, other: &Self) -> Self { *self ^ *other } - fn and(&self, other: &Self) -> Self { *self && *other } - fn not(&self) -> Self { !*self } - fn implies(&self, other: &Self) -> Self { !*self || *other } - fn equivalent(&self, other: &Self) -> Self { *self == *other } - fn equal(&self, other: &Self) -> Self { *self == *other } - fn unequal(&self, other: &Self) -> Self { *self != *other } -} diff --git a/btypes_lazy/src/main/rust/btypes/src/binteger.rs b/btypes_lazy/src/main/rust/btypes/src/binteger.rs deleted file mode 100644 index e3e70874cc1fb28f3648ae9d3f66291047221c42..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/binteger.rs +++ /dev/null @@ -1,138 +0,0 @@ -use std::convert::TryInto; -use crate::bboolean::{BBoolean, BBooleanT}; -use crate::bobject::BObject; - -use std::fmt; -use std::hash::Hash; - -pub trait BInt: BObject { fn get_binteger_value(&self) -> BInteger { panic!("get_integer_value not implemented!"); }} -pub trait FromBInt { fn from<T: BInt>(value: &T) -> Self; } - -#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct BInteger { - val: i64, -} - -impl BObject for BInteger {} -impl BInt for BInteger { - fn get_binteger_value(&self) -> BInteger { return *self; } -} - -impl FromBInt for BInteger { - fn from<T: BInt>(value: &T) -> Self { - return value.get_binteger_value(); - } -} - -impl BInteger { - #![allow(non_snake_case, dead_code)] - - pub const fn new(init: i64) -> BInteger { - return BInteger { - val: init, - } - } - - pub fn get_val(&self) -> i64 { return self.val; } - - pub fn compareTo(&self, o: &BInteger) -> i64 { - return self.val - o.val; - } - - pub fn lessEqual(&self, o: &BInteger) -> BBoolean { - return BBoolean::new(self.val <= o.val); - } - - pub fn greaterEqual(&self, o: &BInteger) -> BBoolean { - return BBoolean::new(self.val >= o.val); - } - - pub fn less(&self, o: &BInteger) -> BBoolean { - return BBoolean::new(self.val < o.val); - } - - pub fn greater(&self, o: &BInteger) -> BBoolean { - return BBoolean::new(self.val > o.val); - } - - pub fn equal(&self, o: &BInteger) -> BBoolean { - return BBoolean::new(self.val == o.val); - } - - pub fn unequal(&self, o: &BInteger) -> BBoolean { - return BBoolean::new(self.val != o.val); - } - - pub fn plus(&self, v: &BInteger) -> BInteger { - return BInteger::new(self.val + v.val); - } - - pub fn minus(&self, v: &BInteger) -> BInteger { - return BInteger::new(self.val - v.val); - } - - pub fn multiply(&self, v: &BInteger) -> BInteger { - return BInteger::new(self.val * v.val); - } - - pub fn power(&self, v: &BInteger) -> BInteger { - if v.val < 0 { panic!("Power with negative exponent!") } - let exp: u32 = v.val.unsigned_abs().try_into().unwrap(); - return BInteger::new(self.val.pow(exp)); - } - - pub fn divide(&self, v: &BInteger) -> BInteger { - return BInteger::new(self.val / v.val); - } - - pub fn modulo(&self, v: &BInteger) -> BInteger { - //return BInteger::new(self.val.rem_euclid(v.val)); - return BInteger::new(self.val % v.val); - } - - pub fn succ(&self) -> BInteger { - return BInteger::new(self.val + 1); - } - - pub fn pred(&self) -> BInteger { - return BInteger::new(self.val - 1); - } - - pub fn negative(&self) -> BInteger { - return BInteger::new(-self.val); - } - - pub fn positive(&self) -> BInteger { - return *self; - } - - pub fn isInteger(&self) -> BBoolean { - return BBoolean::new(true); - } - - pub fn isNotInteger(&self) -> BBoolean { - return BBoolean::new(false); - } - - pub fn isNatural(&self) -> BBoolean { - return BBoolean::new(self.val >= 0); - } - - pub fn isNotNatural(&self) -> BBoolean { - return BBoolean::new(self.val < 0); - } - - pub fn isNatural1(&self) -> BBoolean { - return BBoolean::new(self.val > 0); - } - - pub fn isNotNatural1(&self) -> BBoolean { - return BBoolean::new(self.val < 1); - } -} - -impl fmt::Display for BInteger { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.val) - } -} \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/bobject.rs b/btypes_lazy/src/main/rust/btypes/src/bobject.rs deleted file mode 100644 index a913ee366977ce5b49bbec8353c0e8363623e3cb..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/bobject.rs +++ /dev/null @@ -1,8 +0,0 @@ -use std::hash::Hash; -use std::clone::Clone; -use std::fmt::{Debug, Display}; -use crate::bboolean::{BBoolean, BBooleanT}; - -pub trait BObject: Eq + Hash + Ord + Clone + Display + Debug { - fn is_struct(&self) -> BBoolean { BBoolean::new(false) } -} \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/brelation.rs b/btypes_lazy/src/main/rust/btypes/src/brelation.rs deleted file mode 100644 index d1eab3dffa1067b36e38952b53c5f77198e25e49..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/brelation.rs +++ /dev/null @@ -1,652 +0,0 @@ -#![ allow( dead_code, non_snake_case) ] - -use std::collections::hash_map::DefaultHasher; -use std::collections::LinkedList; -use std::cell::RefCell; -use std::cmp::Ordering; -use crate::bobject::BObject; -use crate::binteger::{BInt, BInteger, FromBInt}; -use crate::btuple::BTuple; - -use std::fmt; -use std::hash::{Hash, Hasher}; -use std::convert::TryInto; -use rand::prelude::IteratorRandom; -use crate::orderedhashset::OrderedHashSet as OrdSet; //TODO try OrdMap instead -use im::OrdMap as HashMap; -use crate::bboolean::{BBoolean, BBooleanT}; -use crate::brelation::CombiningType::{DIFFERENCE, INTERSECTION, UNION}; -use crate::bset::{BSet, SetLike, TBSet}; -use crate::bstring::TBString; -use crate::bstruct::BStruct; - -enum CombiningType { - DIFFERENCE, - INTERSECTION, - UNION -} - -#[derive(Default, Debug, Eq, Clone)] -pub struct BRelation<L: BObject, R: BObject> { - map: HashMap<L, OrdSet<R>>, - hash_cache: RefCell<Option<u64>>, -} - -impl<L: BObject, R: BObject> PartialOrd for BRelation<L, R> { - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { self.map.partial_cmp(&other.map) } - fn lt(&self, other: &Self) -> bool { self.map.lt(&other.map) } - fn le(&self, other: &Self) -> bool { self.map.le(&other.map) } - fn gt(&self, other: &Self) -> bool { self.map.gt(&other.map) } - fn ge(&self, other: &Self) -> bool { self.map.ge(&other.map) } -} - -impl<L: BObject, R: BObject> Ord for BRelation<L, R> { - fn cmp(&self, other: &Self) -> Ordering { self.map.cmp(&other.map) } - fn max(self, other: Self) -> Self { - match self.cmp(&other) { - Ordering::Less => other, - Ordering::Greater => self, - Ordering::Equal => other, - } - } - fn min(self, other: Self) -> Self { - match self.cmp(&other) { - Ordering::Less => self, - Ordering::Greater => other, - Ordering::Equal => self, - } - } - fn clamp(self, min: Self, max: Self) -> Self { - if self < min { - min - } else if self > max { - max - } else { - self - } - } -} - -//TODO: check if replacing cache with mutex works and does not impact permormance too much -unsafe impl<L: BObject, R: BObject> Sync for BRelation<L, R> {} - -impl<L: BObject, R: BObject> PartialEq for BRelation<L, R> { - fn eq(&self, other: &BRelation<L, R>) -> bool { - self.map.eq(&other.map) - } -} - -impl<L: BObject, R: BObject> Hash for BRelation<L, R> { - fn hash<H: Hasher>(self: &BRelation<L, R>, state: &mut H) { - let cache = self.hash_cache.clone().take(); - let hash: u64; - - if cache.is_none() { - let mut hasher = DefaultHasher::new(); - self.map.hash(&mut hasher); - /* - let mut kvs = self.map.iter().collect::<Vec<(&L, &OrdSet<R>)>>(); - kvs.sort_by(|(k1, _v1), (k2, _v2)| k1.cmp(k2)); - for (key, value) in kvs { - key.hash(&mut hasher); - value.iter().for_each(|v| v.hash(&mut hasher)); - } - */ - hash = hasher.finish(); - //println!("BRelation: cache miss"); - self.hash_cache.replace(Option::Some(hash)); - } else { - //println!("BRelation: cache hit"); - hash = cache.unwrap(); - } - hash.hash(state); - } -} - -pub trait TBRelation { - type Left: BObject; - type Right: BObject; - - fn get_as_brelation(&self) -> &BRelation<Self::Left, Self::Right>; - - fn isPartialInteger(&self) -> BBoolean { return BBoolean::new(false); } - fn checkDomainInteger(&self) -> BBoolean { return BBoolean::new(false); } - fn isPartialNatural(&self) -> BBoolean { return BBoolean::new(false); } - fn checkDomainNatural(&self) -> BBoolean { return BBoolean::new(false); } - fn isPartialNatural1(&self) -> BBoolean { return BBoolean::new(false); } - fn checkDomainNatural1(&self) -> BBoolean { return BBoolean::new(false); } - fn checkRangeInteger(&self) -> BBoolean { return BBoolean::new(false); } - fn checkRangeNatural(&self) -> BBoolean { return BBoolean::new(false); } - fn checkRangeNatural1(&self) -> BBoolean { return BBoolean::new(false); } - fn checkDomainString(&self) -> BBoolean { return BBoolean::new(false); } - fn isPartialString(&self) -> BBoolean { return BBoolean::new(false); } - fn checkRangeString(&self) -> BBoolean { return BBoolean::new(false); } - fn checkDomainStruct(&self) -> BBoolean { return BBoolean::new(false); } - fn isPartialStruct(&self) -> BBoolean { return BBoolean::new(false); } - fn checkRangeStruct(&self) -> BBoolean { return BBoolean::new(false); } -} - -impl<L: BObject, R: BObject> fmt::Display for BRelation<L, R> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut result = "{".to_owned(); - let mut first = true; - for (key, range) in self.map.iter() { - for value in range.iter() { - if !first { result = result + ", " } - else { first = false; } - result = result + &format!("({} |-> {})", key, value).to_string(); - } - } - result = result + "}"; - return write!(f, "{}", result); - } -} -impl<L: BObject, R: BObject> TBRelation for BRelation<L, R> { - type Left = L; - type Right = R; - fn get_as_brelation(&self) -> &BRelation<Self::Left, Self::Right> { self } -} -impl<L: BObject, R: BObject> BObject for BRelation<L, R> {} - -impl<L: 'static + BObject, R: 'static + BObject> BRelation<L, R> { - pub fn new(mut args: Vec<BTuple<L, R>>) -> BRelation<L,R> { - let mut ret: BRelation<L, R> = BRelation {map: HashMap::new(), hash_cache: RefCell::new(Option::None) }; - while !args.is_empty() { - let current_tuple = args.remove(0); - ret.insert(¤t_tuple); - } - return ret; - } - - pub fn fromSet(set: BSet<BTuple<L, R>>) -> BRelation<L, R> { - let mut ret: BRelation<L, R> = BRelation {map: HashMap::new(), hash_cache: RefCell::new(Option::None)}; - set.iter().for_each(|current_tuple| ret.insert(current_tuple)); - return ret; - } - - fn insert(&mut self, tuple: &BTuple<L, R>) { - let set = self.map.get(&tuple.projection1()); - let new_set: OrdSet<R>; - if set.is_some() { - new_set = set.unwrap().update(tuple.projection2()); - } else { - new_set = OrdSet::from(vec![tuple.projection2()]); - } - self.map.insert(tuple.projection1(), new_set); - self.hash_cache.replace(Option::None); - } - - fn update(&self, key: L, value: OrdSet<R>) -> Self { - BRelation{ map: self.map.update(key, value), hash_cache: RefCell::new(Option::None) } - } - - fn update_unit(&self, key: L, value: R) -> Self { - self.update(key, OrdSet::unit(value)) - } - - pub fn card(&self) -> BInteger { - return self.size(); - } - - pub fn size(&self) -> BInteger { - let mut size = 0; - for val in self.map.values() { - size += val.len(); - } - return BInteger::new(size.try_into().unwrap()); - } - - pub fn intersect(&self, relation: &BRelation<L, R>) -> BRelation<L, R> { - return self.relation_combine(relation, INTERSECTION) - } - - pub fn difference(&self, relation: &BRelation<L, R>) -> BRelation<L, R> { - return self.relation_combine(relation, DIFFERENCE); - } - - pub fn _union(&self, relation: &BRelation<L, R>) -> BRelation<L, R> { - return self.relation_combine(relation, UNION); - } - - fn relation_combine(&self, relation: &BRelation<L, R>, comb_type: CombiningType) -> BRelation<L, R> { - let other_map = &relation.map; - let other_domain: OrdSet<L> = OrdSet::from(relation.map.keys().cloned().collect::<Vec<L>>()); - let this_domain: OrdSet<L> = OrdSet::from(self.map.keys().cloned().collect::<Vec<L>>()); - let intersection_domain = this_domain.clone().intersection(other_domain.clone()); - let difference_domain = this_domain.relative_complement(other_domain.clone()); - - let loop1_set; - let loop2_set; - match comb_type { - CombiningType::DIFFERENCE => {loop1_set = difference_domain; loop2_set = intersection_domain;} - CombiningType::INTERSECTION => {loop1_set = intersection_domain; loop2_set = difference_domain;} - CombiningType::UNION => {loop1_set = other_domain; loop2_set = OrdSet::new();} - } - - let empty_map = OrdSet::new(); - let mut result_map = BRelation{map: self.map.clone(), hash_cache: RefCell::new(Option::None)}; - for domain_element in loop1_set { - let this_range_set = self.map.get(&domain_element).unwrap_or(&empty_map).clone(); - let other_range_set = other_map.get(&domain_element).unwrap_or(&empty_map).clone(); - let new_range_set; - match comb_type { - CombiningType::DIFFERENCE => {new_range_set = this_range_set.relative_complement(other_range_set);} - CombiningType::INTERSECTION => {new_range_set = this_range_set.intersection(other_range_set);} - CombiningType::UNION => {new_range_set = this_range_set.union(other_range_set);} - } - if new_range_set.is_empty() { - result_map.map.remove(&domain_element); - } else { - result_map.map.insert(domain_element, new_range_set); - } - } - - for domain_element in loop2_set { - result_map.map.remove(&domain_element); - } - - return result_map; - } - - pub fn equal(&self, o: &BRelation<L, R>) -> BBoolean { - return BBoolean::new(self.eq(o)); - } - - pub fn unequal(&self, o: &BRelation<L, R>) -> BBoolean { - return BBoolean::new(!self.eq(o)); - } - - pub fn elementOf(&self, element: &BTuple<L, R>) -> BBoolean { - let prj1 = element.projection1(); - let prj2 = element.projection2(); - return BBoolean::new(self.map.get(&prj1).unwrap_or(&OrdSet::new()).contains(&prj2)); - } - - pub fn notElementOf(&self, element: &BTuple<L, R>) -> BBoolean { - let prj1 = element.projection1(); - let prj2 = element.projection2(); - return BBoolean::new(!self.map.get(&prj1).unwrap_or(&OrdSet::new()).contains(&prj2)); - } - - pub fn relationImage(&self, domain: &BSet<L>) -> BSet<R> { - let result_set = OrdSet::unions(domain.iter().map(|e| self.map.get(&e).unwrap_or(&OrdSet::new()).clone()).into_iter()); - return BSet::fromOrdSet(result_set); - } - - pub fn functionCall(&self, arg: &L) -> R { - let range = self.map.get(arg); - if range.is_none() { - panic!("Argument is not in the domain of this relation"); - } - - return range.unwrap().iter().next().unwrap_or_else(|| panic!("Argument is not in the domain of this relation")).clone(); - } - - pub fn pow(&self) -> BSet<BRelation<L, R>> { return self._pow(true); } - pub fn fin(&self) -> BSet<BRelation<L, R>> { return self.pow(); } - pub fn pow1(&self) -> BSet<BRelation<L, R>> { return self._pow(false); } - pub fn fin1(&self) -> BSet<BRelation<L, R>> { return self.pow1(); } - - fn _pow(&self, with_empty_set: bool) -> BSet<BRelation<L, R>> { - let this_map = &self.map; - - let mut result: BSet<BRelation<L, R>> = BSet::new(vec![]); - let start: BRelation<L, R> = BRelation::new(vec![]); - let mut queue: LinkedList<BRelation<L, R>> = LinkedList::new(); - queue.push_back(start.clone()); - if with_empty_set { result = result._union(&BSet::<BRelation<L, R>>::new(vec![start])); } - while !queue.is_empty() { - let current_set = queue.pop_front().unwrap(); - - for domain_element in self.map.keys() { - let range_option = this_map.get(&domain_element); - if range_option.is_none() { break; } - let mut range = range_option.unwrap().clone(); - while !range.is_empty() { - let range_element = range.remove_min().unwrap(); - let next_relation = current_set._union(&BRelation::fromSet(BSet::new(vec![BTuple::new(domain_element.clone(), range_element)]))); - let previous_size = result.size(); - result = result._union(&BSet::new(vec![next_relation.clone()])); - if previous_size < result.size() { queue.push_back(next_relation) } - } - } - } - return result; - } - - pub fn domain(&self) -> BSet<L> { - let result_set: Vec<L> = self.map.iter().filter_map(|(k, v)| return if !v.is_empty() { Some(k.clone()) } else { None }).collect(); - return BSet::new(result_set); - } - - pub fn range(&self) -> BSet<R> { - if self.map.is_empty() { - return BSet::<R>::new(vec![]); - } else { - return BSet::fromOrdSet(self.map.values().cloned().reduce(|v1, v2| v1.union(v2)).unwrap()); - } - } - - pub fn inverse(&self) -> BRelation<R, L> { - if self.map.is_empty() { - return BRelation::new(vec![]); - } else { - return self.map.iter().fold(BRelation::<R, L>::new(vec![]), - |mut map, (k, v)| { - v.iter().for_each(|cv| map.insert(&BTuple::new(cv.clone(), k.clone()))); - return map - }); - } - } - - pub fn domainRestriction(&self, arg: &BSet<L>) -> BRelation<L, R> { - return self.domainSubstraction(&self.domain().difference(&arg)); - } - - pub fn domainSubstraction(&self, arg: &BSet<L>) -> BRelation<L, R> { - return BRelation {map: arg.iter().fold(self.map.clone(), |map, e| map.without(e)), hash_cache: RefCell::new(Option::None)} - } - - pub fn rangeRestriction(&self, arg: &BSet<R>) -> BRelation<L, R> { - //return self.rangeSubstraction(self.range().difference(arg)); - return self.map.iter().filter_map(|(key, value)| { - let resut_range = BSet::fromOrdSet(value.clone()).intersect(arg); - if resut_range.isEmpty() { Option::None } else { Option::Some((key, resut_range)) } - }).fold(BRelation::<L, R>::new(vec![]), |rel, (key, val)| rel.update(key.clone(), val.as_ord_set())); - } - - pub fn rangeSubstraction(&self, arg: &BSet<R>) -> BRelation<L, R> { - return self.map.iter().filter_map(|(key, value)| { - let resut_range = BSet::fromOrdSet(value.clone()).difference(arg); - if resut_range.isEmpty() { Option::None } else { Option::Some((key, resut_range)) } - }).fold(BRelation::<L, R>::new(vec![]), |rel, (key, val)| rel.update(key.clone(), val.as_ord_set())); - } - - pub fn subset(&self, arg: &BRelation<L, R>) -> BBoolean { - let emptySet = OrdSet::new(); - for (k, v) in self.map.clone() { - let arg_v = arg.map.get(&k).unwrap_or(&emptySet).clone(); - if !v.is_subset(arg_v) { return BBoolean::new(false) } - } - return BBoolean::new(true); - } - - pub fn notSubset(&self, arg: &BRelation<L, R>) -> BBoolean { - return self.subset(arg).not(); - } - - pub fn _override(&self, arg: &BRelation<L, R>) -> BRelation<L, R> { - return BRelation { map: arg.map.clone().union(self.map.clone()), hash_cache: RefCell::new(Option::None)} - } - - pub fn directProduct<ArgR: 'static + BObject>(&self, arg: &BRelation<L, ArgR>) -> BRelation<L, BTuple<R, ArgR>> { - self.map.iter() - .fold(BRelation::<L, BTuple<R, ArgR>>::new(vec![]), - |mut rel, (k, v)| { - let option = arg.map.get(k); - if option.is_some() { - rel.map.insert(k.clone(), BSet::<R>::cartesian::<R, ArgR>(v, option.unwrap())); - } - return rel; - }) - } - - pub fn parallelProduct<ArgL, ArgR>(&self, arg: &BRelation<ArgL, ArgR>) - -> BRelation<BTuple<L, ArgL>, BTuple<R, ArgR>> - where ArgL: 'static + BObject, - ArgR: 'static + BObject { - let mut result_relation: BRelation<BTuple<L, ArgL>, BTuple<R, ArgR>> = BRelation::new(vec![]); - for (this_key, this_range) in self.map.clone() { - for (that_key, that_range) in arg.map.clone() { - result_relation.map.insert(BTuple::new(this_key.clone(), that_key), - BSet::<R>::cartesian::<R, ArgR>(&this_range, &that_range)); - } - } - return result_relation; //TODO? - } - - pub fn composition<NewR: 'static + BObject>(&self, arg: &BRelation<R, NewR>) -> BRelation<L, NewR> { - let mut result_set: BRelation<L, NewR> = BRelation::new(vec![]); - let empty_set = OrdSet::<NewR>::new(); - for (this_key, this_range) in self.map.iter() { - let new_range = this_range.iter().fold(OrdSet::<NewR>::new(), - |set, element| set.union(arg.map.get(element).unwrap_or(&empty_set).clone())); - if !new_range.is_empty() { result_set.map.insert(this_key.clone(), new_range); } - } - return result_set; - } - - pub fn projection1(arg1: &BSet<L>, arg2: &BSet<R>) -> BRelation<BTuple<L,R>,L> { - return arg1.iter().fold(BRelation::new(vec![]), |rel, element1| - arg2.iter().cloned().fold(rel, |nrel, element2| - nrel.update_unit(BTuple::new(element1.clone(), element2), element1.clone()))); - } - - pub fn projection2(arg1: &BSet<L>, arg2: &BSet<R>) -> BRelation<BTuple<L,R>,R> { - return arg1.iter().fold(BRelation::new(vec![]), |rel, element1| - arg2.iter().cloned().fold(rel, |nrel, element2| - nrel.update_unit(BTuple::new(element1.clone(), element2.clone()), element2))); - } - - pub fn fnc(&self) -> BRelation<L, BSet<R>> { - return self.map.iter().fold(BRelation::new(vec![]), |rel, (key, range)| - rel.update_unit(key.clone(), BSet::fromOrdSet(range.clone()))) - } - - pub fn cartesianProduct(set_a: &BSet<L>, set_b: &BSet<R>) -> BRelation<L, R> { - // slightly inefficient due to double iteration - return BSet::<L>::cartesian::<L, R>(&set_a.as_ord_set(), &set_b.as_ord_set()).iter() - .fold(BRelation::new(vec![]), |mut rel, tuple| { rel.insert(tuple); return rel; }); - } - - pub fn nondeterminism(&self) -> BTuple<L, R> { - let mut rng = rand::thread_rng(); - let tuple = self.map.iter().choose(&mut rng).unwrap(); - return BTuple::new(tuple.0.clone(), tuple.1.iter().choose(&mut rng).unwrap().clone()); - } - - pub fn isTotal(&self, domain: &BSet<L>) -> BBoolean { return self.domain().equal(domain); } - pub fn isTotalInteger(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isTotalNatural(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isTotalNatural1(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isTotalString(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isTotalStruct(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isPartial(&self, domain: &BSet<L>) -> BBoolean { return self.domain().subset(domain); } - pub fn checkDomain(&self, domain: &BSet<L>) -> BBoolean { return self.domain().subset(domain); } - pub fn checkRange(&self, range: &BSet<R>) -> BBoolean { return self.range().subset(range); } - - pub fn isRelation(&self) -> BBoolean { return BBoolean::new(true); } - - pub fn isFunction(&self) -> BBoolean { - return BBoolean::new(self.map.values().find(|set| set.len() > 1).is_none()); - } - - pub fn isSurjection(&self, range: &BSet<R>) -> BBoolean { return self.range().equal(range); } - pub fn isSurjectionInteger(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isSurjectionNatural(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isSurjectionNatural1(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isSurjectionString(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isSurjectionStruct(&self) -> BBoolean { return BBoolean::new(false); } - - pub fn isInjection(&self) -> BBoolean { - if self.map.is_empty() { return BBoolean::new(true); } - let mut ranges = self.map.values().cloned(); - let mut checked = ranges.next().unwrap(); - for to_check in ranges { - //current range "hits" and element that was already "hit" before - if !checked.clone().intersection(to_check.clone()).is_empty() { return BBoolean::new(false); } - checked = checked.union(to_check); - } - return BBoolean::new(true); - } - - pub fn isBijection(&self, range: &BSet<R>) -> BBoolean { return self.isSurjection(range).and(&self.isInjection()); } - pub fn isBijectionInteger(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isBijectionNatural(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isBijectionNatural1(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isBijectionString(&self) -> BBoolean { return BBoolean::new(false); } - pub fn isBijectionStruct(&self) -> BBoolean { return BBoolean::new(false); } -} - - -impl<L: 'static + BObject> BRelation<L, L> { - pub fn identity(set: &BSet<L>) -> BRelation<L, L> { - return set.iter().fold(BRelation::<L, L>::new(vec![]), |rel, v| rel.update_unit(v.clone(), v.clone())); - } - - pub fn iterate(&self, n: &BInteger) -> BRelation<L, L> { - return (0..n.get_val()).fold(BRelation::identity(&self.domain()._union(&self.range())), - |rel, _| rel.composition(self)); - } - - pub fn closure(&self) -> BRelation<L, L> { - return self.closure_closure1(false); - } - - pub fn closure1(&self) -> BRelation<L, L> { - return self.closure_closure1(true); - } - - fn closure_closure1(&self, is_closure1: bool) -> BRelation<L, L> { - let mut result = if is_closure1 { BRelation::new(vec![]) } else { self.iterate(&BInteger::new(0)) }; - let mut current_iteration = self.iterate(&BInteger::new(1)); - let mut next_result = result._union(¤t_iteration); - while !result.eq(&next_result) { - result = next_result; - current_iteration = current_iteration.composition(self); - next_result = result._union(¤t_iteration); - } - return result; - } -} - -//sequence -impl<L, R> BRelation<L, R> -where L: 'static + BInt + FromBInt, - R: 'static + BObject { - //this actually works, ridiculous... - pub fn first(&self) -> R { - return self.functionCall(&L::from(&BInteger::new(1))); - } - - pub fn last(&self) -> R { - return self.functionCall(&L::from(&self.card())); - } - - pub fn reverse(&self) -> BRelation<L, R> { - let size = self.card().succ(); - return BRelation { - map: self.map.iter().fold(HashMap::<L, OrdSet<R>>::new(), - |result, (k, v)| - result.update(L::from(&size.minus(&k.get_binteger_value())), v.clone())), - hash_cache: RefCell::new(Option::None) - } - } - - pub fn front(&self) -> BRelation<L, R> { - return self.domainSubstraction(&BSet::new(vec![L::from(&self.card())])); - } - - pub fn tail(&self) -> BRelation<L, R> { - return self.drop(&BInteger::new(1)) - } - - pub fn take(&self, n: &BInteger) -> BRelation<L, R> { - return self.domainRestriction(&BSet::new((1..n.get_val()+1).map(|i| L::from(&BInteger::new(i))).collect())); - } - - pub fn drop(&self, n: &BInteger) -> BRelation<L, R> { - return BSet::<BInteger>::interval(&n.succ(), &self.card()).iter().map(|i| (L::from(&i.minus(n)), L::from(i))) - .fold(BRelation::<L, R>::new(vec![]), |rel, (i, i2)| rel.update(i, self.map.get(&i2).unwrap().clone())); - } - - pub fn concat(&self, arg: &BRelation<L,R>) -> BRelation<L, R> { - return arg.map.iter().fold(self.clone(), |rel, (k, v)| - rel.update(L::from(&k.get_binteger_value().plus(&self.card())), v.clone())); - } - - pub fn append(&self, arg: &R) -> BRelation<L, R> { - return self.update_unit(L::from(&self.card().succ()), arg.clone()); - } - - pub fn prepend(&self, arg: &R) -> BRelation<L, R> { - return self.map.iter().fold(self.clone(), |rel, (k, v)| - rel.update(L::from(&k.get_binteger_value().succ()), v.clone())) - .update_unit(L::from(&self.card().succ()), arg.clone()); - } - - pub fn isPartialInteger(&self) -> BBoolean { return BBoolean::new(true); } - pub fn checkDomainInteger(&self) -> BBoolean { return self.isPartialInteger(); } - pub fn isPartialNatural(&self) -> BBoolean { return self.domain().subsetOfNatural(); } - pub fn checkDomainNatural(&self) -> BBoolean { return self.isPartialNatural(); } - pub fn isPartialNatural1(&self) -> BBoolean { return self.domain().subsetOfNatural1(); } - pub fn checkDomainNatural1(&self) -> BBoolean { return self.isPartialNatural1(); } -} - -impl<L, R> BRelation<L, R> - where L: 'static + BInt + FromBInt, - R: 'static + BObject + TBRelation, - R::Left: 'static + BInt + FromBInt { - - pub fn conc(&self) -> BRelation<R::Left, R::Right> { - return self.map.values().map(|set| set.iter().next().unwrap().get_as_brelation()) - .fold(BRelation::<R::Left, R::Right>::new(vec![]), - |result, next| result.concat(next)); - } -} - -impl<L, R> BRelation<L, R> - where L: 'static + BObject, - R: 'static + BInt + FromBInt { - - pub fn checkRangeInteger(&self) -> BBoolean { return BBoolean::new(true); } - pub fn checkRangeNatural(&self) -> BBoolean { return self.range().subsetOfNatural(); } - pub fn checkRangeNatural1(&self) -> BBoolean { return self.range().subsetOfNatural1(); } -} - -impl<L, R> BRelation<L, R> -where L: 'static + BObject, - R: 'static + BObject + TBSet { - - pub fn rel(&self) -> BRelation<L, R::Item> { - return self.map.iter().fold(BRelation::<L, R::Item>::new(vec![]), |rel, (key, range)| - rel.update(key.clone(), range.iter().next().unwrap().as_ord_set())); - } - -} - -impl<L, R> BRelation<L, R> - where L: 'static + BObject + TBString, - R: 'static + BObject { - - pub fn checkDomainString(&self) -> BBoolean { return BBoolean::new(true); } - pub fn isPartialString(&self) -> BBoolean { return self.checkDomainString(); } -} - -impl<L, R> BRelation<L, R> - where L: 'static + BObject, - R: 'static + BObject + TBString { - - pub fn checkRangeString(&self) -> BBoolean { return BBoolean::new(true); } -} - -impl<L, R> BRelation<L, R> -where L: 'static + BObject + BStruct, - R: 'static + BObject { - - pub fn checkDomainStruct(&self) -> BBoolean { return BBoolean::new(true); } - pub fn isPartialStruct(&self) -> BBoolean { return self.checkDomainStruct(); } -} - -impl<L, R> BRelation<L, R> - where L: 'static + BObject, - R: 'static + BObject + BStruct { - - pub fn checkRangeStruct(&self) -> BBoolean { return BBoolean::new(true); } -} - -impl<L: 'static + BObject, R: 'static + BObject> SetLike for BRelation<L, R> { - fn get_empty() -> Self { BRelation::<L, R>::new(vec![]) } - fn _union(&self, other: &Self) -> Self { self._union(other) } - fn intersect(&self, other: &Self) -> Self { self.intersect(other) } -} \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/bset.rs b/btypes_lazy/src/main/rust/btypes/src/bset.rs deleted file mode 100644 index 4cab3f4971f7e9b0b1680e4ed03df38cd488093a..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/bset.rs +++ /dev/null @@ -1,462 +0,0 @@ -#![ allow( dead_code, non_snake_case) ] - -use crate::bboolean::{IntoBool, BBoolean, BBooleanT}; -use crate::binteger::{BInt, BInteger}; -use crate::bstring::BString; -use crate::bobject::BObject; -use crate::btuple::BTuple; -use crate::orderedhashset::OrderedHashSet as OrdSet; -use crate::lazy_ops::set_ops::setops::{IterWrapper, SetOp, SetOpTraits}; -use crate::lazy_ops::set_ops::union::Union; - -use std::any::TypeId; -use std::borrow::Borrow; -use std::convert::TryInto; -use im::ordset::Iter; -use std::hash::{Hash, Hasher}; -use std::collections::LinkedList; -use std::fmt; -use std::fmt::Debug; -use rand::Rng; - -pub trait TBSet: BObject { - type Item: BObject; - - fn as_ord_set(&self) -> OrdSet<Self::Item>; - fn as_bset(&self) -> &BSet<Self::Item>; -} - -pub trait SetLike: BObject { - fn get_empty() -> Self; - fn _union(&self, other: &Self) -> Self; - fn intersect(&self, other: &Self) -> Self; -} - -#[derive(Default, Debug, Eq, PartialOrd, Ord, Clone)] -pub struct BSet<T: BObject> { - set: OrdSet<T>, - transformation: Option<Box<dyn SetOp<Item = T>>>, -} - -impl<T: BObject> BSet<T> { - const OP_NAME: &'static str = "set"; -} - -impl<T: 'static + BObject> SetOp for BSet<T> { - fn compute(&self, _: &BSet<Self::Item>) -> BSet<Self::Item> { - match self.transformation.borrow() { - Some(trans) => trans.compute(&self) , //todo save computation? - None => self.clone(), - } - } - - fn clone_box(&self) -> Box<dyn SetOp<Item=Self::Item>> { - Box::new(self.clone()) - } - - fn get_op_name(&self) -> &str { - return BSet::<T>::OP_NAME; - } - - fn get_rhs(&self) -> Option<Box<dyn SetOp<Item=Self::Item>>> { - return self.transformation.clone(); - } - - fn to_string(&self, _lhs: Option<&str>) -> String { - let mut result = "{".to_owned(); - let mut first = true; - for e in self.set.iter() { - if !first { result = result + ", " } - else { first = false; } - result = result + &format!("{}", e).to_string(); - } - result = result + "}"; - match &self.transformation { - Some(op) => return op.to_string(Option::Some(result.as_str())), - None => return result, - } - } -} - -impl<T: BObject> SetOpTraits for BSet<T> { - type Item = T; - - fn iter_lazy<'a>(&'a self, _lhs: &BSet<Self::Item>) -> IterWrapper<T> { - match &self.transformation { - Some(op) => op.iter_lazy(self), - None => IterWrapper::single(self.iter_directly()), - } - } - - fn contains_lazy(&self, _lhs: &BSet<Self::Item>, o: &Self::Item) -> bool { - match &self.transformation { - Some(op) => op.contains_lazy(self, o), - None => self.contains_directly(o), - } - } - - fn is_empty_lazy(&self, _lhs: &BSet<Self::Item>) -> bool { - match &self.transformation { - Some(op) => op.is_empty_lazy(self), - None => self.is_empty_directly(), - } - } - - fn size_lazy(&self, _lhs: &BSet<Self::Item>) -> usize { - let self_clone = self.clone(); - match self.transformation { - Some(ref op) => op.size_lazy(&self_clone), - None => self.size_directly(), - } - } -} - -impl<I: BObject> Hash for BSet<I> { - fn hash<H: Hasher>(self: &BSet<I>, state: &mut H) { self.set.hash(state); } -} - -impl<I: BObject> PartialEq for BSet<I> { - fn eq(&self, other: &BSet<I>) -> bool { - if self.size() != other.size() { return false; } - for i in self.iter() { - if !other.contains(i) { return false; } - } - return true; - } -} - -impl<T: 'static + BObject> BObject for BSet<T> {} - -impl<T: 'static + BObject> TBSet for BSet<T> { - type Item = T; - fn as_ord_set(&self) -> OrdSet<Self::Item> { self.set.clone() } - fn as_bset(&self) -> &BSet<Self::Item> { self } -} - -impl<T: 'static + BObject> fmt::Display for BSet<T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - return write!(f, "{}", <BSet<T> as SetOp>::to_string(self, Option::None)); - } -} -/* -impl<'a, T: 'static + BObject> IntoIterator for &'a BSet<T> -where - T: 'a + Ord, -{ - type Item = &'a T; - type IntoIter = im::ordset::Iter<'a, T>; - - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} -*/ -//TODO: check if replacing cache with mutex works and does not impact permormance too much -unsafe impl<T: BObject> Sync for BSet<T> {} - -impl<T: BObject> BSet<T> { - pub fn size(&self) -> usize { self.size_lazy(self) } - pub fn iter(&self) -> impl Iterator<Item = &T> + '_ { self.iter_lazy(self) } - pub fn iter_directly(&self) -> Iter<T> { self.set.iter() } - pub fn contains(&self, o: &T) -> bool { self.contains_lazy(self, o) } - pub fn contains_directly(&self, o: &T) -> bool { return self.set.contains(o); } - pub fn size_directly(&self) -> usize { return self.set.len(); } - pub fn is_empty_directly(&self) -> bool { return self.set.is_empty() } -} - -impl<T: 'static + BObject> BSet<T> { - - pub fn new(mut args: Vec<T>) -> BSet<T> { - let mut ret: BSet<T> = BSet { - set: OrdSet::new(), - transformation: Option::None - }; - while !args.is_empty() { - ret.set.insert(args.remove(0)); - } - return ret; - } - - pub fn fromOrdSet(set: OrdSet<T>) -> BSet<T> { - return BSet { set: set, transformation: Option::None }; - } - - pub fn get_direct_set(&self) -> Self { - return BSet { set: self.set.clone(), transformation: Option::None } - } - - pub fn iter_complete<'a>(&'a self) -> IterWrapper<T> { self.iter_lazy(self) } - - pub fn isEmpty(&self) -> bool { return self.is_empty_lazy(self); } - - pub fn intersect(&self, set: &BSet<T>) -> BSet<T> { - return BSet{ set: self.set.clone().intersection(set.set.clone()), transformation: Option::None }; - } - - pub fn difference(&self, set: &BSet<T>) -> BSet<T> { - let result: OrdSet<T> = self.iter().fold(OrdSet::new(), |r_set, element| if set.contains(element) { r_set } else { r_set.update(element.clone()) }); - return BSet::fromOrdSet(result); - } - - pub fn _union(&self, set: &BSet<T>) -> BSet<T> { - return BSet { set: self.set.clone(), transformation: Option::Some(Box::new(Union::new(set.clone())))} - } - - pub fn real_union(&self, set: &BSet<T>) -> BSet<T> { - return BSet{ set: self.set.clone().union(set.set.clone()), transformation: Option::None }; - } - - pub fn interval(a: &BInteger, b: &BInteger) -> BSet<BInteger> { - let mut result: BSet<BInteger> = BSet::new(vec![]); - for i in a.get_val()..b.get_val()+1 { - result.set.insert(BInteger::new(i)); - } - return result; - } - - pub fn card(&mut self) -> BInteger { - return self._size(); - } - - pub fn _size(&mut self) -> BInteger { - return BInteger::new(self.size().try_into().unwrap()); - } - - pub fn elementOf(&self, object: &T) -> BBoolean { - return BBoolean::new(self.contains(object)); - } - - pub fn notElementOf(&self, object: &T) -> BBoolean { - return BBoolean::new(!self.contains(object)); - } - - pub fn subset(&self, set: &BSet<T>) -> BBoolean { - return BBoolean::new(self.set.is_subset(&set.set)); - } - - pub fn notSubset(&self, set: &BSet<T>) -> BBoolean { - return self.subset(set).not(); - } - - pub fn strictSubset(&mut self, set: &mut BSet<T>) -> BBoolean { - return BBoolean::new(self.size() < set.size() && self.subset(set)); - } - - pub fn strictNotSubset(&mut self, set: &mut BSet<T>) -> BBoolean { - return BBoolean::new(self.size() >= set.size() || !self.subset(set)); - } - - pub fn fin(&self) -> BSet<BSet<T>> { - return self.pow(); - } - - pub fn pow(&self) -> BSet<BSet<T>> { - return self._pow(true); - } - - pub fn fin1(&self) -> BSet<BSet<T>> { - return self.pow1(); - } - - pub fn pow1(&self) -> BSet<BSet<T>> { - return self._pow(false); - } - - fn _pow(&self, with_empty_set: bool) -> BSet<BSet<T>> { - let mut result: BSet<BSet<T>> = BSet::new(vec![]); - let start: BSet<T> = BSet::new(vec![]); - let mut queue: LinkedList<BSet<T>> = LinkedList::new(); - queue.push_back(start.clone()); - if with_empty_set { result = result._union(&BSet::new(vec![start])); } - - while !queue.is_empty() { - let current_set: BSet<T> = queue.pop_front().unwrap(); - for element in self.set.iter() { - let next_set: BSet<T> = current_set._union(&BSet::new(vec![element.clone()])); - let previous_size = result.size(); - result = result._union(&BSet::new(vec![next_set.clone()])); - if previous_size < result.size() { - queue.push_back(next_set); - } - } - } - - return result; - } - - pub fn nondeterminism(&self) -> T { - let mut rng = rand::thread_rng(); - return self.iter().nth(rng.gen_range(0..self.set.len())).unwrap().clone(); - } - - pub fn equal(&self, other: &BSet<T>) -> BBoolean { - return BBoolean::new(self.eq(other)); - } - - pub fn unequal(&self, other: &BSet<T>) -> BBoolean { - return BBoolean::new(!self.eq(other)); - } - - pub fn subsetOfInteger(&self) -> BBoolean { - return BBoolean::new(TypeId::of::<BInteger>() == TypeId::of::<T>()); - } - - pub fn strictSubsetOfInteger(&self) -> BBoolean { - return self.subsetOfInteger(); - } - - pub fn notSubsetOfInteger(&self) -> BBoolean { - return self.subsetOfInteger().not(); - } - - pub fn equalInteger(&self) -> BBoolean { - return BBoolean::new(false); - } - - pub fn unequalInteger(&self) -> BBoolean { - return BBoolean::new(true); - } - - pub fn equalNatural(&self) -> BBoolean { - return BBoolean::new(false); - } - - pub fn unequalNatural(&self) -> BBoolean { - return BBoolean::new(true); - } - - pub fn equalNatural1(&self) -> BBoolean { - return BBoolean::new(false); - } - - pub fn unequalNatural1(&self) -> BBoolean { - return BBoolean::new(true); - } - - pub fn equalString(&self) -> BBoolean { - return BBoolean::new(false); - } - - pub fn unequalString(&self) -> BBoolean { - return BBoolean::new(true); - } - - pub fn equalStruct(&self) -> BBoolean { - return BBoolean::new(false); - } - - pub fn unequalStruct(&self) -> BBoolean { - return BBoolean::new(true); - } - - pub fn subsetOfString(&self) -> BBoolean { - return BBoolean::new(TypeId::of::<BString>() == TypeId::of::<T>()); - } - - pub fn strictSubsetOfString(&self) -> BBoolean { - return self.subsetOfString(); - } - - pub fn notSubsetOfString(&self) -> BBoolean { - return self.subsetOfString().not(); - } - - pub fn notStrictSubsetOfString(&self) -> BBoolean { - return self.strictSubsetOfString().not(); - } - - pub fn subsetOfStruct(&self) -> BBoolean { - return self.is_struct(); - } - - pub fn strictsubsetOfStruct(&self) -> BBoolean { - return self.subsetOfStruct(); - } - - pub fn notsubsetOfStruct(&self) -> BBoolean { - return self.subsetOfStruct().not(); - } - - pub fn notStrictsubsetOfStruct(&self) -> BBoolean { - return self.strictsubsetOfStruct().not(); - } - - //rust specific - pub fn cartesian<T1: 'static + BObject, T2: 'static + BObject>(set_a: &OrdSet<T1>, set_b: &OrdSet<T2>) -> OrdSet<BTuple<T1, T2>> { - if set_a.is_empty() || set_b.is_empty() {return OrdSet::<BTuple<T1, T2>>::new();} - return set_a.iter() - .fold(OrdSet::<BTuple<T1, T2>>::new(), - |set, lhs| set_b.iter().cloned() - .fold(set, - |tset, rhs| tset.update(BTuple::new(lhs.clone(), rhs)))) - } -} - -impl<T: 'static + BInt> BSet<T> { - - pub fn notStrictSubsetOfInteger(&self) -> BBoolean { - return self.strictSubsetOfInteger().not(); - } - - pub fn subsetOfNatural(&self) -> BBoolean { - if self.subsetOfInteger().booleanValue() { - return BBoolean::new(self.set.iter().find(|i| i.get_binteger_value().isNotNatural().booleanValue()).is_none()); - } - return BBoolean::new(false); - } - - pub fn strictSubsetOfNatural(&self) -> BBoolean { - return self.subsetOfNatural(); - } - - pub fn notSubsetOfNatural(&self) -> BBoolean { - return self.subsetOfNatural().not(); - } - - pub fn notStrictSubsetOfNatural(&self) -> BBoolean { - return self.strictSubsetOfNatural().not(); - } - - pub fn subsetOfNatural1(&self) -> BBoolean { - if self.subsetOfInteger().booleanValue() { - return BBoolean::new(self.set.iter().find(|i| i.get_binteger_value().isNotNatural1().booleanValue()).is_none()); - } - return BBoolean::new(false); - } - - pub fn strictSubsetOfNatural1(&self) -> BBoolean { - return self.subsetOfNatural(); - } - - pub fn notSubsetOfNatural1(&self) -> BBoolean { - return self.subsetOfNatural1().not(); - } - - pub fn notStrictSubsetOfNatural1(&self) -> BBoolean { - return self.strictSubsetOfNatural1().not(); - } - - pub fn _min(self: &BSet<T>) -> BInteger { - return self.set.get_min().unwrap().get_binteger_value(); - } - - pub fn _max(self: &BSet<T>) -> BInteger { - return self.set.get_max().unwrap().get_binteger_value(); - } -} - -impl<T: 'static + BObject> SetLike for BSet<T> { - fn get_empty() -> Self { BSet::<T>::new(vec![]) } - fn _union(&self, other: &Self) -> Self { self._union(other) } - fn intersect(&self, other: &Self) -> Self { self.intersect(other) } -} - -impl<T: 'static + SetLike> BSet<T> { - pub fn unary__union(&self) -> T { - return self.iter().fold(T::get_empty(), |result, next| result._union(next)); - } - - pub fn unary_intersect(&self) -> T { - return self.iter().fold(T::get_empty(), |result, next| result.intersect(next)); - } -} \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/bstring.rs b/btypes_lazy/src/main/rust/btypes/src/bstring.rs deleted file mode 100644 index e49302b41c87b2d8b511fd4bad1b10456db9e2e8..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/bstring.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::fmt::{Display, Formatter}; -use crate::bobject::BObject; - -#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct BString { - val: String, -} - -pub trait TBString {} - -impl TBString for BString {} - -impl Display for BString { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.val) - } -} - -impl BObject for BString {} \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/bstruct.rs b/btypes_lazy/src/main/rust/btypes/src/bstruct.rs deleted file mode 100644 index ca151047b3a4cf9c69f159a08cd1f9a00a7aa1a6..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/bstruct.rs +++ /dev/null @@ -1,6 +0,0 @@ -use crate::bboolean::{BBoolean, BBooleanT}; -use crate::bobject::BObject; - -pub trait BStruct: BObject{ - fn is_struct(&self) -> BBoolean { BBoolean::new(true) } -} \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/btuple.rs b/btypes_lazy/src/main/rust/btypes/src/btuple.rs deleted file mode 100644 index 31779d4b33902a8e1a064477a9aca0159d74a9d7..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/btuple.rs +++ /dev/null @@ -1,35 +0,0 @@ -use crate::bobject::BObject; -use std::fmt; - -#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct BTuple<L: BObject, R: BObject>{ - left_val: L, - right_val: R, -} - -impl<L: BObject, R: BObject> fmt::Display for BTuple<L, R> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - return write!(f, "({} |-> {})", self.left_val, self.right_val); - } -} - -impl<L: BObject, R:BObject> BObject for BTuple<L, R>{} - -impl<L: BObject, R: BObject> BTuple<L, R> { - pub fn new(left: L, right: R) -> BTuple<L, R> { - return BTuple {left_val: left, right_val: right,}; - } - - pub fn from_refs(left: &L, right: &R) -> BTuple<L, R> { - return BTuple {left_val: left.clone(), right_val: right.clone(),}; - } - - pub fn projection1(&self) -> L { - return self.left_val.clone(); - } - - pub fn projection2(&self) -> R { - return self.right_val.clone(); - } - -} diff --git a/btypes_lazy/src/main/rust/btypes/src/butils.rs b/btypes_lazy/src/main/rust/btypes/src/butils.rs deleted file mode 100644 index dc5e4835e4e5689e41450769c411309f7667f415..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/butils.rs +++ /dev/null @@ -1,6 +0,0 @@ -use crate::bboolean::{BBoolean, BBooleanT}; -use crate::bset::BSet; - -lazy_static! { - pub static ref BOOL: BSet<BBoolean> = BSet::new(vec![BBoolean::new(true), BBoolean::new(false)]); -} \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/lazy_ops/mod.rs b/btypes_lazy/src/main/rust/btypes/src/lazy_ops/mod.rs deleted file mode 100644 index 032fa0acb3fa7131be974169637c97365c39e609..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/lazy_ops/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod set_ops; \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/identity.rs b/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/identity.rs deleted file mode 100644 index e88fb8ae9cc262aad73fa1def659a40b05b221b7..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/identity.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::bobject::BObject; -use crate::bset::BSet; -use crate::lazy_ops::set_ops::setops::{SetOp, SetOpTraits}; - -use std::fmt; -use std::fmt::{Debug, Formatter}; -use std::marker::PhantomData; - - -#[derive(Clone)] -pub struct Identity<T: BObject> { - phantom: PhantomData<T>, -} - -impl<T: BObject> Identity<T> { - const OP_NAME: &'static str = "Identity"; -} - -impl<T: BObject> Debug for Identity<T> { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "Identity()") - } -} - -impl<T: 'static + BObject> SetOp for Identity<T> { - - fn compute(&self, lhs: &BSet<T>) -> BSet<T> { - lhs.clone() - } - - fn clone_box(&self) -> Box<dyn SetOp<Item=Self::Item>> { - Box::new(Identity{phantom: PhantomData}) - } - - fn get_op_name(&self) -> &str { - return Identity::<T>::OP_NAME; - } - - fn get_rhs(&self) -> Option<Box<dyn SetOp<Item=Self::Item>>> { - return Option::None; - } -} - -impl<T: 'static + BObject> SetOpTraits for Identity<T>{ - type Item = T; - - fn contains_lazy(&self, lhs: &BSet<Self::Item>, o: &Self::Item) -> bool { lhs.contains_directly(o) } - fn is_empty_lazy(&self, lhs: &BSet<Self::Item>) -> bool { lhs.is_empty_directly() } - fn size_lazy(&self, lhs: &BSet<Self::Item>) -> usize { lhs.size_directly() } -} \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/mod.rs b/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/mod.rs deleted file mode 100644 index 6ee6fe5523a65fca3f8fb0bbc15d23715008ceac..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod setops; -//pub mod identity; -pub mod union; \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/setops.rs b/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/setops.rs deleted file mode 100644 index 6e9bc5f3fa7d2652f43fb5b6def78b0a0cb6fb98..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/setops.rs +++ /dev/null @@ -1,184 +0,0 @@ -use std::hash::{Hasher}; -use std::cmp::Ordering; -use std::fmt::{Debug}; -use im::ordset::Iter; - -use crate::bobject::BObject; -use crate::bset::BSet; - -pub trait SetOp: SetOpTraits + Debug { - - fn compute(&self, lhs: &BSet<Self::Item>) -> BSet<Self::Item>; - fn clone_box(&self) -> Box<dyn SetOp<Item = Self::Item>>; - - fn get_op_name(&self) -> &str; - fn get_rhs(&self) -> Option<Box<dyn SetOp<Item = Self::Item>>>; - - fn to_string(&self, lhs: Option<&str>) -> String { - let mut result = format!("{}(", self.get_op_name()); - let mut has_lhs = false; - if lhs.is_some() { - result.push_str(lhs.unwrap()); - has_lhs = true; - } - match self.get_rhs() { - Some(v) => { - if has_lhs { result.push_str(", "); } - result.push_str(format!("{}", v.to_string(Option::None)).as_str()) - }, - None => {}, - } - result.push_str(")"); - - return result; - } - - //PartialEq - fn eq_box(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> bool { - self.get_op_name().eq(other.get_op_name()) && self.get_rhs().eq(&other.get_rhs()) - } - - //PartialOrd - fn partial_cmp_box(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> Option<Ordering> { - let mut result = self.get_op_name().partial_cmp(other.get_op_name()); - if result.is_some() { - if result.clone().unwrap().eq(&Ordering::Equal) { - result = self.get_rhs().partial_cmp(&other.get_rhs()); - } - } - return result; - } - - //Ord - fn cmp_box(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> Ordering { - let mut result = self.get_op_name().cmp(other.get_op_name()); - if result.eq(&Ordering::Equal) { - result = self.get_rhs().cmp(&other.get_rhs()); - } - return result; - } - fn lt(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> bool { self.cmp_box(other).eq(&Ordering::Less) } - fn le(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> bool { [Ordering::Less, Ordering::Equal].contains(&self.cmp_box(other)) } - fn gt(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> bool { self.cmp_box(other).eq(&Ordering::Greater) } - fn ge(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> bool { [Ordering::Greater, Ordering::Equal].contains(&self.cmp_box(other)) } - - fn max(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> Box<dyn SetOp<Item = Self::Item>> { - match self.cmp_box(other) { - Ordering::Less => other.clone(), - Ordering::Equal => other.clone(), - Ordering::Greater => self.clone_box(), - } - } - - fn min(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> Box<dyn SetOp<Item = Self::Item>> { - match self.cmp_box(other) { - Ordering::Less => self.clone_box(), - Ordering::Equal => self.clone_box(), - Ordering::Greater => other.clone(), - } - } - - fn clamp(&self, min: &Box<dyn SetOp<Item = Self::Item>>, max: &Box<dyn SetOp<Item = Self::Item>>) -> Box<dyn SetOp<Item = Self::Item>> { - if self.lt(min) { - return min.clone() - } else if self.gt(max) { - max.clone() - } else { - self.clone_box() - } - } -} - -pub trait SetOpTraits { - type Item: BObject; - - fn iter_lazy<'a>(&'a self, lhs: &'a BSet<Self::Item>) -> IterWrapper<'a, Self::Item>; - fn contains_lazy(&self, lhs: &BSet<Self::Item>, o:&Self::Item) -> bool; - fn is_empty_lazy(&self, lhs: &BSet<Self::Item>) -> bool; - fn size_lazy(&self, lhs: &BSet<Self::Item>) -> usize; - //fn hash_val(&self) -> u64; -} - -pub enum IterWrapperE<'a, T: BObject> { - Empty, - Single(Iter<'a, T>), - Chain(Box<IterWrapper<'a, T>>, Box<IterWrapper<'a, T>>), - Filtered(Box<IterWrapper<'a, T>>, BSet<T>), -} - -pub struct IterWrapper<'a, T: BObject> { - iter: IterWrapperE<'a, T>, -} - -impl<'a, T: BObject> IterWrapper<'a, T> { - pub fn empty() -> IterWrapper<'a, T> { IterWrapper { iter: IterWrapperE::Empty }} - pub fn single(iter: Iter<'a, T>) -> IterWrapper<'a, T> { IterWrapper { iter: IterWrapperE::Single(iter)} } - pub fn chain(iter_a: IterWrapper<'a, T>, iter_b: IterWrapper<'a, T>) -> IterWrapper<'a, T> { - IterWrapper { iter: IterWrapperE::Chain(Box::new(iter_a), - Box::new(iter_b))} - } - pub fn filtered(iter: IterWrapper<'a, T>, filter: BSet<T>) -> IterWrapper<'a, T> { - IterWrapper { iter: IterWrapperE::Filtered(Box::new(iter), filter)} - } -} - -impl<'a, T: BObject> Iterator for IterWrapper<'a, T> { - type Item = &'a T; - - fn next(&mut self) -> Option<Self::Item> { - match self.iter { - IterWrapperE::Empty => Option::None, - IterWrapperE::Single(ref mut s) => s.next(), - IterWrapperE::Chain(ref mut a, ref mut b) => { - let option_a = a.next(); - match option_a { - Some(result) => Some(result), - None => b.next(), - } - }, - IterWrapperE::Filtered(ref mut i, ref filter) => { - let mut option = i.next(); - while option.is_some() { - let val = option.unwrap(); - if !filter.contains(val) { return Option::Some(val); } - option = i.next(); - } - return option; - } - } - } -} - - -impl<T: BObject> Clone for Box<dyn SetOp<Item = T>> { - fn clone(&self) -> Self { - self.clone_box() - } -} - -impl<T: BObject> Eq for Box<dyn SetOp<Item=T>> {} - -impl<T: BObject> PartialEq<Self> for Box<dyn SetOp<Item=T>> { - fn eq(&self, other: &Self) -> bool { - self.eq_box(other) - } -} - -impl<T: BObject> PartialOrd<Self> for Box<dyn SetOp<Item=T>> { - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - self.partial_cmp_box(other) - } -} - -impl<T: BObject> Ord for Box<dyn SetOp<Item = T>> { - fn cmp(&self, other: &Self) -> Ordering { - self.cmp_box(other) - } -} -/* -impl<T: 'static + BObject> Default for Box<dyn SetOp<Item = T>> { - fn default() -> Box<Self> { - Box::new(Identity {phantom: PhantomData}) - } -} -*/ \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/union.rs b/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/union.rs deleted file mode 100644 index 74ab40b71a2fcc0c7c8f465a3f5fccd8c62a40b2..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/lazy_ops/set_ops/union.rs +++ /dev/null @@ -1,88 +0,0 @@ -use std::cell::RefCell; -use crate::bobject::BObject; -use crate::bset::BSet; -use crate::lazy_ops::set_ops::setops::{IterWrapper, SetOp, SetOpTraits}; - -use std::fmt; -use std::fmt::{Debug, Formatter}; -use std::ops::Not; - -#[derive(Clone)] -pub struct Union<T: BObject> { - rhs: BSet<T>, - rhs_is_reduced: bool, -} - -impl<T: BObject> Union<T> { - const OP_NAME: &'static str = "Union"; -} - -impl<T: 'static + BObject> Debug for Union<T> { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "Union({})", self.rhs) - } -} - -impl<T: BObject> Union<T> { - pub fn new(rhs: BSet<T>) -> Union<T> { - Union {rhs: rhs, rhs_is_reduced: false} - } -} - -impl<T: 'static + BObject> Union<T> { - fn check_reduced(&mut self, lhs: &BSet<T>) { - if !self.rhs_is_reduced { - let new_rhs = self.rhs.difference(&lhs.get_direct_set()); - self.rhs = new_rhs; - self.rhs_is_reduced = true; - } - } -} - -impl<T: 'static + BObject> SetOpTraits for Union<T>{ - type Item = T; - - fn iter_lazy<'a>(&'a self, lhs: &'a BSet<Self::Item>) -> IterWrapper<'a, T> { - //self.check_reduced(lhs); <-- would need me to make this function take &mut self, which would propagate to BSet::iter, which would break everything... - let iter_a = IterWrapper::single(lhs.iter_directly()); - let iter_b = self.rhs.iter_complete(); - if self.rhs_is_reduced { - return IterWrapper::chain(iter_a, iter_b); - } - return IterWrapper::chain(iter_a, IterWrapper::filtered(iter_b, lhs.get_direct_set())); - } - - fn contains_lazy(&self, lhs: &BSet<Self::Item>, o: &Self::Item) -> bool { - lhs.contains_directly(o) || self.rhs.contains(o) - } - - fn is_empty_lazy(&self, lhs: &BSet<Self::Item>) -> bool { - lhs.is_empty_directly() && self.rhs.isEmpty() - } - - fn size_lazy(&self, lhs: &BSet<Self::Item>) -> usize { - if self.rhs_is_reduced { - return lhs.size_directly() + self.rhs.size(); - } - return lhs.size_directly() + self.rhs.difference(&lhs.get_direct_set()).size(); - } -} - -impl<T: 'static + BObject> SetOp for Union<T> { - fn compute(&self, lhs: &BSet<T>) -> BSet<T> { - lhs.real_union(&self.rhs) - } - - fn clone_box(&self) -> Box<dyn SetOp<Item=Self::Item>> { - Box::new(Union{rhs: self.rhs.clone(), - rhs_is_reduced: self.rhs_is_reduced}) - } - - fn get_op_name(&self) -> &str { - return Union::<T>::OP_NAME; - } - - fn get_rhs(&self) -> Option<Box<dyn SetOp<Item=Self::Item>>> { - return Option::Some(self.rhs.clone_box()); - } -} \ No newline at end of file diff --git a/btypes_lazy/src/main/rust/btypes/src/lib.rs b/btypes_lazy/src/main/rust/btypes/src/lib.rs deleted file mode 100644 index 67e1bf40dc81246dc1ddce46c9ac766da5f579eb..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[macro_use] -extern crate lazy_static; - -pub mod bboolean; -pub mod binteger; -pub mod bobject; -pub mod bstruct; -pub mod bset; -pub mod bstring; -pub mod btuple; -pub mod brelation; -pub mod butils; -pub mod orderedhashset; -pub mod lazy_ops; diff --git a/btypes_lazy/src/main/rust/btypes/src/orderedhashset.rs b/btypes_lazy/src/main/rust/btypes/src/orderedhashset.rs deleted file mode 100644 index 8b9c7fd5c824bbd816d753f0f72ed04667363a40..0000000000000000000000000000000000000000 --- a/btypes_lazy/src/main/rust/btypes/src/orderedhashset.rs +++ /dev/null @@ -1,148 +0,0 @@ -use std::borrow::Borrow; -use std::collections::hash_map::DefaultHasher; -use std::cell::RefCell; -use std::cmp::Ordering; -use std::hash::{Hash, Hasher}; - -use im::OrdSet; -use im::ordset::Iter; -use crate::bobject::BObject; - -#[derive(Default, Debug, Eq)] -pub struct OrderedHashSet<I: BObject> { - set: OrdSet<I>, - hash_cache: RefCell<Option<u64>>, -} - -impl<I: BObject> Clone for OrderedHashSet<I> { - fn clone(&self) -> Self { - OrderedHashSet { set: self.set.clone(), hash_cache: RefCell::new(self.hash_cache.borrow().clone()) } - } -} - -impl<I: BObject> PartialOrd for OrderedHashSet<I> { - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { self.set.partial_cmp(&other.set) } - fn lt(&self, other: &Self) -> bool { self.set.lt(&other.set) } - fn le(&self, other: &Self) -> bool { self.set.le(&other.set) } - fn gt(&self, other: &Self) -> bool { self.set.gt(&other.set) } - fn ge(&self, other: &Self) -> bool { self.set.ge(&other.set) } -} - -impl<I: BObject> Ord for OrderedHashSet<I> { - fn cmp(&self, other: &Self) -> Ordering { self.set.cmp(&other.set) } - fn max(self, other: Self) -> Self { - match self.cmp(&other) { - Ordering::Less => other, - Ordering::Greater => self, - Ordering::Equal => other, - } - } - fn min(self, other: Self) -> Self { - match self.cmp(&other) { - Ordering::Less => self, - Ordering::Greater => other, - Ordering::Equal => self, - } - } - fn clamp(self, min: Self, max: Self) -> Self { - if self < min { - min - } else if self > max { - max - } else { - self - } - } -} - -//TODO: check if replacing cache with mutex works and does not impact permormance too much -unsafe impl<T: BObject> Sync for OrderedHashSet<T> {} - -impl<I: BObject> PartialEq for OrderedHashSet<I> { - fn eq(&self, other: &Self) -> bool { - self.set.eq(&other.set) - } -} - -impl<I: BObject> Hash for OrderedHashSet<I> { - fn hash<H: Hasher>(self: &OrderedHashSet<I>, state: &mut H) { - let cache = self.hash_cache.borrow().clone(); - let hash: u64; - - if cache.is_none() { - let mut hasher = DefaultHasher::new(); - self.set.hash(&mut hasher); - hash = hasher.finish(); - self.hash_cache.replace(Option::Some(hash)); - } else { - hash = cache.unwrap(); - } - hash.hash(state); - } -} - -impl<A: BObject> IntoIterator for OrderedHashSet<A> { - type Item = A; - type IntoIter = im::ordset::ConsumingIter<A>; - - fn into_iter(self) -> Self::IntoIter { - self.set.into_iter() - } -} - -impl<I: BObject> OrderedHashSet<I> { - pub fn new() -> Self { Self::from_set(OrdSet::new()) } - - pub fn from_set(val: OrdSet<I>) -> Self { OrderedHashSet {set: val, hash_cache: RefCell::new(Option::None)} } - - pub fn unit(item: I) -> Self { Self::from_set(OrdSet::unit(item)) } - - pub fn from(items: Vec<I>) -> Self { Self::from_set(OrdSet::from(items)) } - - pub fn update(&self, item: I) -> Self { Self::from_set(self.set.update(item)) } - - pub fn unions<A: IntoIterator<Item = Self>>(a: A) -> Self { - a.into_iter().fold(Self::new(), Self::union) - } - - pub fn iter<'a>(&'a self) -> Iter<'a, I> { self.set.iter() } - - pub fn len(&self) -> usize { self.set.len() } - pub fn is_empty(&self) -> bool { self.set.is_empty() } - - pub fn contains(&self, value: &I) -> bool { self.set.contains(value) } - pub fn is_subset<RS: Borrow<Self>>(&self, other: RS) -> bool { - let other = other.borrow(); - self.set.is_subset(&other.set) - } - - pub fn insert(&mut self, value: I) -> Option<I> { - self.hash_cache.replace(Option::None); - return self.set.insert(value); - } - - pub fn remove_min(&mut self) -> Option<I> { - self.hash_cache.replace(Option::None); - return self.set.remove_min() - } - - pub fn get_min(&self) -> Option<&I> { self.set.get_min() } - pub fn get_max(&self) -> Option<&I> { self.set.get_max() } - - pub fn union(self, other: Self) -> Self { - self.hash_cache.replace(Option::None); - return Self::from_set(self.set.union(other.set)); - } - - pub fn intersection(self, other: Self) -> Self { - self.hash_cache.replace(Option::None); - return Self::from_set(self.set.intersection(other.set)); - } - - pub fn relative_complement(self, other: Self) -> Self { - self.hash_cache.replace(Option::None); - return Self::from_set(self.set.relative_complement(other.set)); - } - - pub fn get_set(self) -> OrdSet<I> { return self.set } -} \ No newline at end of file