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(&current_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(&current_iteration);
-        while !result.eq(&next_result) {
-            result = next_result;
-            current_iteration = current_iteration.composition(self);
-            next_result = result._union(&current_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