diff --git a/Makefile b/Makefile
index eadb0c2a48fda95d9627b27866cad7550d91dbc1..21d10eff90773e8e7ce353d28f55637d81e8dfc7 100644
--- a/Makefile
+++ b/Makefile
@@ -46,8 +46,9 @@ endif
 ifneq (,$(findstring $(LANGUAGE), rs|RS|rust|Rust))
 %:
 	java -jar B2Program-all-0.1.0-SNAPSHOT.jar $(RS_CODE_GEN_FLAGS) -f $(DIRECTORY)/$@.mch
+	mkdir -p ./btypes_primitives/src/main/rust/bmachine/src/
 	mv $(DIRECTORY)/$@.rs ./btypes_primitives/src/main/rust/bmachine/src/main.rs
-	mv $(DIRECTORY)/*.rs ./btypes_primitives/src/main/rust/bmachine/src/
+	find $(DIRECTORY) -maxdepth 1 -type f -name "*.rs" -exec mv -v '{}' ./btypes_primitives/src/main/rust/bmachine/src/ \;
 	cargo run --release --manifest-path ./btypes_primitives/src/main/rust/bmachine/Cargo.toml -- $(STRATEGY) $(THREADS) $(CACHING)
 endif
 endif
diff --git a/btypes_primitives/src/main/rust/bmachine/Cargo.toml b/btypes_primitives/src/main/rust/bmachine/Cargo.toml
index 1f4c46e38bde5648b94b4d5e195236ccd4c1d26d..148b6bc0a6810d1e851133b9f689a4a399f66f84 100644
--- a/btypes_primitives/src/main/rust/bmachine/Cargo.toml
+++ b/btypes_primitives/src/main/rust/bmachine/Cargo.toml
@@ -10,7 +10,7 @@ rand = "0.8.3"
 im = "15.0.0"
 threadpool = "1.8.1"
 derivative = "2.2.0"
-dashmap = "5.1.0"
+dashmap = "~5.1.0"
 btypes = { path = "../btypes" }
 
 [profile.release]
diff --git a/btypes_primitives/src/main/rust/btypes/src/brelation.rs b/btypes_primitives/src/main/rust/btypes/src/brelation.rs
index 2b9cac648fa5ccd76766dffe6c447182e3f2e5e8..1153cf4706de600dc0f4082c2cc32d4fa628db52 100644
--- a/btypes_primitives/src/main/rust/btypes/src/brelation.rs
+++ b/btypes_primitives/src/main/rust/btypes/src/brelation.rs
@@ -12,7 +12,7 @@ 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 crate::orderedhashset::OrderedHashSet as OrdSet;
 use im::OrdMap as HashMap;
 use crate::bboolean::{BBoolean, BBooleanT};
 use crate::brelation::CombiningType::{DIFFERENCE, INTERSECTION, UNION};
@@ -67,7 +67,6 @@ impl<L: BObject, R: BObject> Ord for BRelation<L, R> {
     }
 }
 
-//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> {
@@ -443,6 +442,36 @@ impl<L: 'static + BObject, R: 'static + BObject> BRelation<L, R> {
     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); }
+
+    //equals BRelation.checkDomain(BRelation)
+    pub fn check_domain_of<I: 'static + BObject>(&self, of: &BRelation<BTuple<L, R>, I>) -> BBoolean {
+        return self.is_superset(&of.domain());
+    }
+
+    //equals BRelation.checkRange(BRelation)
+    pub fn check_range_of<I: 'static + BObject>(&self, of: &BRelation<I, BTuple<L, R>>) -> BBoolean {
+        return self.is_superset(&of.range());
+    }
+
+    pub fn check_partial_of<I: 'static + BObject>(&self, of: &BRelation<BTuple<L, R>, I>) -> BBoolean {
+        return self.is_superset(&of.domain());
+    }
+
+    pub fn check_total_of<I: 'static + BObject>(&self, of: &BRelation<BTuple<L, R>, I>) -> BBoolean {
+        let of_domain = &of.domain();
+        return self.size().equal(&of_domain._size()) && self.is_superset(of_domain);
+    }
+
+    pub fn is_superset(&self, other: &BSet<BTuple<L, R>>) -> BBoolean {
+        for element in other.iter() {
+            match self.map.get(&element.projection1()) {
+                Some(range) => if !range.contains(&element.projection2()) { return false } ,
+                None => return false,
+            }
+        }
+        return true;
+    }
+
     pub fn checkRange(&self, range: &BSet<R>) -> BBoolean { return self.range().subset(range); }
 
     pub fn isRelation(&self) -> BBoolean { return BBoolean::new(true); }
@@ -639,4 +668,4 @@ 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_primitives/src/main/rust/btypes/src/bset.rs b/btypes_primitives/src/main/rust/btypes/src/bset.rs
index 6510e30f7a928488e678fccf44299d81906141fc..0d0147b5d226a84aac55754b0c4933f93473b9d5 100644
--- a/btypes_primitives/src/main/rust/btypes/src/bset.rs
+++ b/btypes_primitives/src/main/rust/btypes/src/bset.rs
@@ -14,6 +14,7 @@ use std::hash::Hash;
 use std::collections::LinkedList;
 use std::fmt;
 use rand::Rng;
+use crate::brelation::BRelation;
 
 pub trait TBSet: BObject {
     type Item: BObject;
@@ -67,7 +68,6 @@ where
     }
 }
 
-//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: 'static + BObject> BSet<T> {
@@ -290,6 +290,28 @@ impl<T: 'static + BObject> BSet<T> {
         return self.strictsubsetOfStruct().not();
     }
 
+    //equals BRelation.checkDomain(BSet)
+    pub fn check_domain_of<I: 'static + BObject>(&self, of: &BRelation<T, I>) -> BBoolean {
+        return self.is_superset(&of.domain());
+    }
+
+    //equals BRelation.checkRange(BSet)
+    pub fn check_range_of<I: 'static + BObject>(&self, of: &BRelation<I, T>) -> BBoolean {
+        return self.is_superset(&of.range());
+    }
+
+    pub fn check_partial_of<I: 'static + BObject>(&self, of: &BRelation<T, I>) -> BBoolean {
+        return self.is_superset(&of.domain());
+    }
+
+    pub fn is_superset(&self, other: &BSet<T>) -> BBoolean {
+        return other.subset(self);
+    }
+
+    pub fn check_total_of<I: 'static + BObject>(&self, of: &BRelation<T, I>) -> BBoolean {
+        return self.equal(&of.domain());
+    }
+
     //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();}
diff --git a/src/main/java/de/hhu/stups/codegenerator/generators/RelationSetGenerator.java b/src/main/java/de/hhu/stups/codegenerator/generators/RelationSetGenerator.java
index b83b2f315b133cbeb571be60bafbe4020abffe6a..e43dc25ed885f4d240a89a5d5a03adc2f7575a18 100644
--- a/src/main/java/de/hhu/stups/codegenerator/generators/RelationSetGenerator.java
+++ b/src/main/java/de/hhu/stups/codegenerator/generators/RelationSetGenerator.java
@@ -171,17 +171,17 @@ public class RelationSetGenerator {
             return infiniteSetGenerator.generateInfiniteTotalPartial(node, operator, domain);
         }
 
-        ST template = currentGroup.getInstanceOf("relation_total_partial");
-        TemplateHandler.add(template, "arg", machineGenerator.visitExprNode(lhs, null));
+        ST template;
         if(TOTAL_EXPRESSIONS.contains(operator)) {
-            TemplateHandler.add(template, "operator", "isTotal");
+            template = currentGroup.getInstanceOf("relation_is_total");
         } else if(PARTIAL_EXPRESSIONS.contains(operator)) {
-            TemplateHandler.add(template, "operator", "isPartial");
+            template = currentGroup.getInstanceOf("relation_is_partial");
         } else {
             //Must be empty because predicate can be optional
             return "";
         }
 
+        TemplateHandler.add(template, "arg", machineGenerator.visitExprNode(lhs, null));
         TemplateHandler.add(template, "domain", machineGenerator.visitExprNode(domain, null));
         return template.render();
     }
diff --git a/src/main/resources/de/hhu/stups/codegenerator/CppTemplate.stg b/src/main/resources/de/hhu/stups/codegenerator/CppTemplate.stg
index d4e9b65857e0b0b71c04a41c04f0a6dd157da72e..958aac19ddae73f52c375e17e293ed992867cdb2 100644
--- a/src/main/resources/de/hhu/stups/codegenerator/CppTemplate.stg
+++ b/src/main/resources/de/hhu/stups/codegenerator/CppTemplate.stg
@@ -954,8 +954,12 @@ relation_check_range(arg, range) ::= <<
 (<arg>.checkRange(<range>))
 >>
 
-relation_total_partial(arg, operator, domain) ::= <<
-(<arg>.<operator>(<domain>))
+relation_is_total(arg, domain) ::= <<
+(<arg>.isTotal(<domain>))
+>>
+
+relation_is_partial(arg, domain) ::= <<
+(<arg>.isPartial(<domain>))
 >>
 
 relation_function(arg, operator) ::= <<
diff --git a/src/main/resources/de/hhu/stups/codegenerator/JavaTemplate.stg b/src/main/resources/de/hhu/stups/codegenerator/JavaTemplate.stg
index 324401c4f2b75f7323a4973bacbd96522ddc77da..2f3750edaeaa8e52377fdb114eb9790eef5b829b 100644
--- a/src/main/resources/de/hhu/stups/codegenerator/JavaTemplate.stg
+++ b/src/main/resources/de/hhu/stups/codegenerator/JavaTemplate.stg
@@ -1132,8 +1132,12 @@ relation_check_range(arg, range) ::= <<
 <arg>.checkRange(<range>)
 >>
 
-relation_total_partial(arg, operator, domain) ::= <<
-<arg>.<operator>(<domain>)
+relation_is_total(arg, domain) ::= <<
+<arg>.isTotal(<domain>)
+>>
+
+relation_is_partial(arg, domain) ::= <<
+<arg>.isPartial(<domain>)
 >>
 
 relation_function(arg, operator) ::= <<
diff --git a/src/main/resources/de/hhu/stups/codegenerator/PrologTemplate.stg b/src/main/resources/de/hhu/stups/codegenerator/PrologTemplate.stg
index 7536289b016ba7175b29cef1007298fa6749aad6..ed2ea7dee1b7570d7326544a39926cede64a1752 100644
--- a/src/main/resources/de/hhu/stups/codegenerator/PrologTemplate.stg
+++ b/src/main/resources/de/hhu/stups/codegenerator/PrologTemplate.stg
@@ -437,8 +437,12 @@ relation_surjection(arg, range) ::= <<
     % relation_surjection
 >>
 
-relation_total_partial(arg, operator, domain) ::= <<
-    % relation_total_partial
+relation_is_total(arg, domain) ::= <<
+    % relation_is_total
+>>
+
+relation_is_partial(arg, domain) ::= <<
+    % relation_is_partial
 >>
 
 relation_type(leftType, rightType) ::= <<
diff --git a/src/main/resources/de/hhu/stups/codegenerator/PythonTemplate.stg b/src/main/resources/de/hhu/stups/codegenerator/PythonTemplate.stg
index 7b8e443bd6591ba76049e40a61503f9b1a6c9587..5e70e5ad28ab761850eaa71c59e53f03c78a0327 100644
--- a/src/main/resources/de/hhu/stups/codegenerator/PythonTemplate.stg
+++ b/src/main/resources/de/hhu/stups/codegenerator/PythonTemplate.stg
@@ -644,8 +644,12 @@ relation_check_range(arg, range) ::= <<
 <arg>.checkRange(<range>)
 >>
 
-relation_total_partial(arg, operator, domain) ::= <<
-<arg>.<operator>(<domain>)
+relation_is_total(arg, domain) ::= <<
+<arg>.isTotal(<domain>)
+>>
+
+relation_is_partial(arg, domain) ::= <<
+<arg>.isPartial(<domain>)
 >>
 
 relation_function(arg, operator) ::= <<
diff --git a/src/main/resources/de/hhu/stups/codegenerator/RustTemplate.stg b/src/main/resources/de/hhu/stups/codegenerator/RustTemplate.stg
index 537d37f9233f7f879d250d46dfd89e49df94eecd..4885e4d9194b8c87a193f14cf4996099cf93de35 100644
--- a/src/main/resources/de/hhu/stups/codegenerator/RustTemplate.stg
+++ b/src/main/resources/de/hhu/stups/codegenerator/RustTemplate.stg
@@ -332,12 +332,13 @@ let mut <identifier> = BRelation::\<<leftType>, <rightType>\>::new(vec![]);
 >>
 
 lambda_expression(otherIterationConstructs, relation, element, expression, emptyPredicate, predicate, leftType, rightType) ::= <<
+//lambda_expression
 <otherIterationConstructs>
 <if(emptyPredicate)>
-<relation> = <relation>._union(&BRelation::\<<leftType>, <rightType>\>::new(vec![BTuple::new(<element>, <expression>)]));
+<relation> = <relation>._union(&BRelation::\<<leftType>, <rightType>\>::new(vec![BTuple::new(<element>.clone(), <expression>)]));
 <else>
 if (<predicate>).booleanValue() {
-    <relation> = <relation>._union(&BRelation::\<<leftType>, <rightType>\>::new(vec![BTuple::new(<element>, <expression>)]));
+    <relation> = <relation>._union(&BRelation::\<<leftType>, <rightType>\>::new(vec![BTuple::new(<element>.clone(), <expression>)]));
 }
 <endif>
 >>
@@ -675,15 +676,19 @@ relation_predicate(predicates, checkElementOf) ::= <<
 >>
 
 relation_check_domain(arg, domain) ::= <<
-<arg>.checkDomain(&<domain>)
+<domain>.check_domain_of(&<arg>)
 >>
 
 relation_check_range(arg, range) ::= <<
-<arg>.checkRange(&<range>)
+<range>.check_range_of(&<arg>)
 >>
 
-relation_total_partial(arg, operator, domain) ::= <<
-<arg>.<operator>(&<domain>)
+relation_is_total(arg, domain) ::= <<
+<domain>.check_total_of(&<arg>)
+>>
+
+relation_is_partial(arg, domain) ::= <<
+<domain>.check_partial_of(&<arg>)
 >>
 
 relation_function(arg, operator) ::= <<
diff --git a/src/main/resources/de/hhu/stups/codegenerator/TsTemplate.stg b/src/main/resources/de/hhu/stups/codegenerator/TsTemplate.stg
index c4fc08080e1d7b045807a65526542d9490c42e24..96fc5b2aaec9bb9817fd1ae7f1cb9baf2a84a65e 100755
--- a/src/main/resources/de/hhu/stups/codegenerator/TsTemplate.stg
+++ b/src/main/resources/de/hhu/stups/codegenerator/TsTemplate.stg
@@ -804,8 +804,12 @@ relation_check_range(arg, range) ::= <<
 <arg>.checkRange(<range>)
 >>
 
-relation_total_partial(arg, operator, domain) ::= <<
-<arg>.<operator>(<domain>)
+relation_is_total(arg, domain) ::= <<
+<arg>.isTotal(<domain>)
+>>
+
+relation_is_partial(arg, domain) ::= <<
+<arg>.isPartial(<domain>)
 >>
 
 relation_function(arg, operator) ::= <<