diff --git a/btypes_primitives/src/main/rust_embedded/btypes/src/brelation.rs b/btypes_primitives/src/main/rust_embedded/btypes/src/brelation.rs
index 7e5b87959a481bbac3756e0f7e12c35429b21ad6..fd3811bdfff11a4ea970566f29d6563ccb6ac07a 100644
--- a/btypes_primitives/src/main/rust_embedded/btypes/src/brelation.rs
+++ b/btypes_primitives/src/main/rust_embedded/btypes/src/brelation.rs
@@ -324,9 +324,9 @@ impl<L, const LS: usize, R, const RS: usize, const REL_SIZE: usize> BRelation<L,
     //TODO: directProduct/ParallelProduct maybe?
 
     //TODO: support const-params in template? maybe compiler can figure them out itself?
-    pub fn composition<NewR, const NewRS: usize, const ParamTotal: usize, const NewTotal: usize>(&self, arg: &BRelation<R, RS, NewR, NewRS, ParamTotal>) -> BRelation<L, LS, NewR, NewRS, NewTotal>
-    where NewR: SetItem<NewRS>{
-        let mut result = BRelation::<L, LS, NewR, NewRS, NewTotal>::empty();
+    pub fn composition<NewR, const NEW_RS: usize, const PARAM_TOTAL: usize, const NEW_TOTAL: usize>(&self, arg: &BRelation<R, RS, NewR, NEW_RS, PARAM_TOTAL>) -> BRelation<L, LS, NewR, NEW_RS, NEW_TOTAL>
+    where NewR: SetItem<NEW_RS>{
+        let mut result = BRelation::<L, LS, NewR, NEW_RS, NEW_TOTAL>::empty();
         for left_idx in 0..LS {
             result.rel[left_idx] = arg.relationImage(&BSet::const_from_arr(self.rel[left_idx])).as_arr()
         }
@@ -337,10 +337,10 @@ impl<L, const LS: usize, R, const RS: usize, const REL_SIZE: usize> BRelation<L,
     //      or we use the relation-item enums for the tuples as well...
 
     //TODO: support const-params in template? maybe compiler can figure them out itself?
-    pub fn fnc<NewR, const NewRS: usize, const newRelTotal: usize>(&self) -> BRelation<L, LS, NewR, NewRS, newRelTotal>
-    where NewR: Set<RS> + SetItem<NewRS>{                                  //BRelation<L, LS, BSet<R, RS>, NewRS, newRelTotal
+    pub fn fnc<NewR, const NEW_RS: usize, const NEW_REL_TOTAL: usize>(&self) -> BRelation<L, LS, NewR, NEW_RS, NEW_REL_TOTAL>
+    where NewR: Set<RS> + SetItem<NEW_RS>{                                  //BRelation<L, LS, BSet<R, RS>, NewRS, newRelTotal
         //NewR::ItemType = R; not yet supported in rust, NewR: Set<RS, I = R> might be, but I'd need to rewrite the trait for that and the related code. For now, we assume the code-generator creates correct code (if it wouldn't the code probably wouldn't run anyway...)
-        let mut result = BRelation::<L, LS, NewR, NewRS, newRelTotal>::empty();
+        let mut result = BRelation::<L, LS, NewR, NEW_RS, NEW_REL_TOTAL>::empty();
         for left_idx in 0..LS {
             result.rel[left_idx][NewR::from_arr(self.rel[left_idx]).as_idx()] = true;
         }
diff --git a/btypes_primitives/src/main/rust_embedded/btypes/src/bset.rs b/btypes_primitives/src/main/rust_embedded/btypes/src/bset.rs
index 9c55da831763a47142e8af1b254bb38ec2722eb4..8826b2e7076713dbb73f3dedbb02e7d69c52a18c 100644
--- a/btypes_primitives/src/main/rust_embedded/btypes/src/bset.rs
+++ b/btypes_primitives/src/main/rust_embedded/btypes/src/bset.rs
@@ -2,7 +2,9 @@
 
 use core::fmt::Debug;
 use core::marker::PhantomData;
+use crate::bboolean::BBoolean;
 use crate::binteger::BInteger;
+use crate::brelation::BRelation;
 
 /// Used to map an Enum to the position in a Set of it's type. \
 /// This is necessary since, even though a [BSet] is alway represented as a flat, 1D-array,
@@ -128,6 +130,9 @@ impl<const SETVARIANTS: usize, const ITEMVARIANTS: usize, const A: usize, I> Pow
 
 pub trait PowAble<const SETLEN: usize, const ITEMVARS: usize>: Set<SETLEN> + SetItem<ITEMVARS> {
     fn pow(&self) -> BSet<Self, ITEMVARS>;
+    fn pow1(&self) -> BSet<Self, ITEMVARS>;
+    fn fin(&self) -> BSet<Self, ITEMVARS> { self.pow() }
+    fn fin1(&self) -> BSet<Self, ITEMVARS> { self.pow1() }
 }
 
 /// To generate the powerset of a BSet we need the corresponding enum already generated.
@@ -145,6 +150,13 @@ impl<const SETLEN: usize, const ITEMVARS: usize , I> PowAble<SETLEN, ITEMVARS> f
         }
         return result;
     }
+
+    fn pow1(&self) -> BSet<Self, ITEMVARS> {
+        let mut result = self.pow();
+        //remove empty set (usually, the index should always be 0, but this ensures that we get the correct one)
+        result.arr[Self::from_arr([false; SETLEN]).as_idx()] = false;
+        return result;
+    }
 }
 
 
@@ -157,7 +169,8 @@ impl<I: SetItem<SIZE>, const SIZE: usize> BSet<I, SIZE> {
 
     pub fn is_empty(&self) -> bool { !self.arr.contains(&true) }
 
-    pub fn equal(&self, other: &Self) -> bool { self.arr.eq(&other.arr) }
+    pub fn equal(&self, other: &Self) -> BBoolean { self.arr.eq(&other.arr) }
+    pub fn unequal(&self, other: &Self) -> BBoolean { !self.arr.eq(&other.arr) }
 
     pub fn card(&self) -> BInteger {
         return self.arr.iter().fold(0,
@@ -165,7 +178,10 @@ impl<I: SetItem<SIZE>, const SIZE: usize> BSet<I, SIZE> {
                                                                  else { size });
     }
 
-    pub fn subset(&self, other: &Self) -> bool { self.subset_of(other) }
+    pub fn subset(&self, other: &Self) -> BBoolean { self.subset_of(other) }
+    pub fn strictSubset(&self, other: &Self) -> BBoolean { self.card() < other.card() && self.subset_of(other) }
+    pub fn notSubset(&self, other: &Self) -> BBoolean { !self.subset_of(other) }
+    pub fn strictNotSubset(&self, other: &Self) -> BBoolean { self.card() >= other.card() || self.notSubset(other) }
 
     pub fn _union(&self, other: &Self) -> Self {
         let mut result = self.copy();
@@ -192,8 +208,107 @@ impl<I: SetItem<SIZE>, const SIZE: usize> BSet<I, SIZE> {
     }
 
     //name hard-coded in b2program
-    pub fn elementOf(&self, element: &I) -> bool { self.arr[element.as_idx()] }
-    pub fn notElementOf(&self, element: &I) -> bool { !self.arr[element.as_idx()] }
+    pub fn elementOf(&self, element: &I) -> BBoolean { self.arr[element.as_idx()] }
+    pub fn notElementOf(&self, element: &I) -> BBoolean { !self.arr[element.as_idx()] }
+
+    //TODO: interval(a: Binteger, b: BInteger) -> BSet<BInteger>
+    //      currently, Int-Sets/Relations are not supported though
+    //TODO: nondeterminism needs external libraries
+
+    pub const fn subsetOfInteger(&self) -> BBoolean { false }
+
+    pub const fn strictSubsetOfInteger(&self) -> BBoolean { return self.subsetOfInteger(); }
+
+    pub const fn notSubsetOfInteger(&self) -> BBoolean { return !self.subsetOfInteger(); }
+
+    pub const fn equalInteger(&self) -> BBoolean { false }
+
+    pub const fn unequalInteger(&self) -> BBoolean { true }
+
+    pub const fn equalNatural(&self) -> BBoolean { false }
+
+    pub const fn unequalNatural(&self) -> BBoolean { true }
+
+    pub const fn equalNatural1(&self) -> BBoolean { false }
+
+    pub const fn unequalNatural1(&self) -> BBoolean { true }
+
+    pub const fn equalString(&self) -> BBoolean { false }
+
+    pub const fn unequalString(&self) -> BBoolean { true }
+
+    pub const fn equalStruct(&self) -> BBoolean { false }
+
+    pub const fn unequalStruct(&self) -> BBoolean { true }
+
+    pub const fn subsetOfString(&self) -> BBoolean { !todo!() }
+
+    pub const fn strictSubsetOfString(&self) -> BBoolean { return self.subsetOfString(); }
+
+    pub const fn notSubsetOfString(&self) -> BBoolean { return !self.subsetOfString(); }
+
+    pub const fn notStrictSubsetOfString(&self) -> BBoolean { return !self.strictSubsetOfString(); }
+
+    pub const fn subsetOfStruct(&self) -> BBoolean { false } //TODO?
+
+    pub const fn strictsubsetOfStruct(&self) -> BBoolean { return self.subsetOfStruct(); }
+
+    pub const fn notsubsetOfStruct(&self) -> BBoolean { return !self.subsetOfStruct(); }
+
+    pub const fn notStrictsubsetOfStruct(&self) -> BBoolean { return !self.strictsubsetOfStruct(); }
+
+    //equals BRelation.checkDomain(BSet)
+    pub fn check_domain_of<R: SetItem<RS>, const RS: usize, const TOTAL_REL: usize>(&self, of: &BRelation<I, SIZE, R, RS, TOTAL_REL>) -> BBoolean {
+        return self.is_superset(&of.domain());
+    }
+
+    //equals BRelation.checkRange(BSet)
+    pub fn check_range_of<L: SetItem<LS>, const LS: usize, const TOTAL_REL: usize>(&self, of: &BRelation<L, LS, I, SIZE, TOTAL_REL>) -> BBoolean {
+        return self.is_superset(&of.range());
+    }
+
+    pub fn check_partial_of<R: SetItem<RS>, const RS: usize, const TOTAL_REL: usize>(&self, of: &BRelation<I, SIZE, R, RS, TOTAL_REL>) -> BBoolean {
+        return self.is_superset(&of.domain());
+    }
+
+    pub fn is_superset(&self, other: &Self) -> BBoolean { return other.subset(self); }
+
+    pub fn check_total_of<R: SetItem<RS>, const RS: usize, const TOTAL_REL: usize>(&self, of: &BRelation<I, SIZE, R, RS, TOTAL_REL>) -> BBoolean {
+        return self.equal(&of.domain());
+    }
+}
+
+trait NestedSet<const OUTER_SIZE: usize, const INNER_SIZE: usize>: Set<OUTER_SIZE> {
+    type InnerSet: Set<INNER_SIZE> + SetItem<INNER_SIZE>;
+
+    fn unary__union(&self) -> BSet<Self::InnerSet, INNER_SIZE> { self.unary__combine(|l, r| l || r) }
+    fn unary__intersect(&self) -> BSet<Self::InnerSet, INNER_SIZE> { self.unary__combine(|l, r| l && r) }
+    fn unary__combine(&self, comb_fn: fn(left_bool:bool, right_bool: bool) -> bool) -> BSet<Self::InnerSet, INNER_SIZE>;
+}
+
+/// Implements functions for netsted-Sets.
+/// A nested-Set is still just a 1D-array, but the Set-Item implements the Set-trait,
+/// so the index can be converted to another 1D-array (this then being the representation of the inners Sets)
+///
+/// Because Rust is a bit constrained in how these implementations can be defined, we need to use
+/// a trait to define how the specific Set should look, and then implement that trait generically for
+/// any I that conforms to further constrictions.
+/// (This will ulitmately only apply to BSets where the inner-type is also a BSet.)
+impl<const OUTER_SIZE: usize, const INNER_SIZE: usize, I> NestedSet<OUTER_SIZE, INNER_SIZE> for I
+where I: Set<OUTER_SIZE>,
+      I::ItemType: Set<INNER_SIZE> + SetItem<INNER_SIZE>{
+    type InnerSet = I::ItemType;
+
+    fn unary__combine(&self, comb_fn: fn(left_bool:bool, right_bool: bool) -> bool) -> BSet<Self::InnerSet, INNER_SIZE> {
+        let mut result_arr = [false; INNER_SIZE]; // empty array representation of the inner settype
+        for outer_idx in 0..OUTER_SIZE {
+            if self.contains_idx(outer_idx) {
+                let inner_set_arr = I::ItemType::from_idx(outer_idx).as_arr(); // array representation of the current inner-set
+                for inner_idx in 0..INNER_SIZE { result_arr[inner_idx] = comb_fn(result_arr[inner_idx], inner_set_arr[inner_idx]); } // logical combination between the arrays (or = union; and = intersection between sets)
+            }
+        }
+        return BSet::<Self::InnerSet, INNER_SIZE>::const_from_arr(result_arr);
+    }
 }
 
 pub struct BSetIter<I: SetItem<SIZE>, const SIZE: usize> {