From 9ff55e2a9a3fce7132745710943e5d896787b70f Mon Sep 17 00:00:00 2001
From: Cookiebowser <lucas.doering@live.de>
Date: Mon, 1 Aug 2022 12:46:05 +0200
Subject: [PATCH] added checkDomain/Range/Partial/Total for Relation parameter

split relation_total_partial template to match other operations
---
 Makefile                                      |  3 +-
 .../src/main/rust/bmachine/Cargo.toml         |  2 +-
 .../src/main/rust/btypes/src/brelation.rs     | 35 +++++++++++++++++--
 .../src/main/rust/btypes/src/bset.rs          | 24 ++++++++++++-
 .../generators/RelationSetGenerator.java      |  8 ++---
 .../hhu/stups/codegenerator/CppTemplate.stg   |  8 +++--
 .../hhu/stups/codegenerator/JavaTemplate.stg  |  8 +++--
 .../stups/codegenerator/PrologTemplate.stg    |  8 +++--
 .../stups/codegenerator/PythonTemplate.stg    |  8 +++--
 .../hhu/stups/codegenerator/RustTemplate.stg  | 17 +++++----
 .../de/hhu/stups/codegenerator/TsTemplate.stg |  8 +++--
 11 files changed, 103 insertions(+), 26 deletions(-)

diff --git a/Makefile b/Makefile
index eadb0c2a4..21d10eff9 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 1f4c46e38..148b6bc0a 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 2b9cac648..1153cf470 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 6510e30f7..0d0147b5d 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 b83b2f315..e43dc25ed 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 d4e9b6585..958aac19d 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 324401c4f..2f3750eda 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 7536289b0..ed2ea7dee 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 7b8e443bd..5e70e5ad2 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 537d37f92..4885e4d91 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 c4fc08080..96fc5b2aa 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) ::= <<
-- 
GitLab