diff --git a/btypes_primitives/src/main/rust_embedded/btypes/src/binteger.rs b/btypes_primitives/src/main/rust_embedded/btypes/src/binteger.rs index 5281ec5b5d8f3673fc2928bedbf314b511f6f996..4eedd407e793ad56482b3e7f69d26ac6f509823a 100644 --- a/btypes_primitives/src/main/rust_embedded/btypes/src/binteger.rs +++ b/btypes_primitives/src/main/rust_embedded/btypes/src/binteger.rs @@ -1,8 +1,14 @@ -#![allow(non_snake_case)] +#![allow(non_snake_case, non_camel_case_types)] use core::convert::TryInto; +use crate::bset::{BSet, SetItem}; pub type BInteger = i128; +pub type set_BInteger = BSet<BInteger, INTEGER_SIZE>; + +pub const LOWER_BOUND: BInteger = -10; +pub const UPPER_BOUND: BInteger = 10; +pub const INTEGER_SIZE: usize = 21; //UB - LB + 1 pub trait BInt { fn equal(&self, other: &Self) -> bool; @@ -48,4 +54,23 @@ impl BInt for BInteger { fn negative(&self) -> Self { -self } fn pred(&self) -> Self { self - 1 } fn succ(&self) -> Self { self + 1 } -} \ No newline at end of file +} + + + +impl SetItem<INTEGER_SIZE> for BInteger { + fn as_idx(&self) -> usize { + if self < &LOWER_BOUND || self > &UPPER_BOUND { + panic!("Integer {} out of Integer bounds!", self); + } + return (self - LOWER_BOUND).try_into().unwrap(); + } + + fn from_idx(idx: usize) -> Self { + if idx > INTEGER_SIZE { + panic!("Integer-index {} is too large!", idx); + } + let bint_idx: BInteger = idx.try_into().unwrap(); + return bint_idx + LOWER_BOUND; + } +} 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 84f2a9685aa5a14d6427e4809add708cfd729af8..df77276d22da99d28117b9931c86f207e04e8fc4 100644 --- a/btypes_primitives/src/main/rust_embedded/btypes/src/bset.rs +++ b/btypes_primitives/src/main/rust_embedded/btypes/src/bset.rs @@ -3,7 +3,8 @@ use core::fmt::Debug; use core::marker::PhantomData; use crate::bboolean::BBoolean; -use crate::binteger::BInteger; +use crate::binteger; +use crate::binteger::{BInt, BInteger, set_BInteger}; use crate::brelation::BRelation; /// Used to map an Enum to the position in a Set of it's type. \ @@ -211,15 +212,15 @@ impl<I: SetItem<SIZE>, const SIZE: usize> BSet<I, SIZE> { 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 fn interval(a: &BInteger, b: &BInteger) -> binteger::set_BInteger { + let mut result = set_BInteger::empty(); + for idx in a.as_idx()..=b.as_idx() { + result.arr[idx] = true; + } + return result; + } pub const fn equalInteger(&self) -> BBoolean { false } @@ -277,6 +278,63 @@ impl<I: SetItem<SIZE>, const SIZE: usize> BSet<I, SIZE> { return self.equal(&of.domain()); } } + +impl <I: SetItem<SIZE> + BInt, const SIZE: usize> BSet<I, SIZE> { + + pub const fn subsetOfInteger(&self) -> BBoolean { true } + + pub const fn notSubsetOfInteger(&self) -> BBoolean { !self.subsetOfInteger() } + + pub const fn strictSubsetOfInteger(&self) -> BBoolean { self.subsetOfInteger() } + + pub fn notStrictSubsetOfInteger(&self) -> BBoolean { !self.strictSubsetOfInteger() } + + pub fn subsetOfNatural(&self) -> BBoolean { + if binteger::LOWER_BOUND < 0 { // if LB >= 0, every Int-set only holds Integers >= 0 + for idx in 0..BInteger::as_idx(&0) { + if self.arr[idx] { return false; } + } + } + return true; + } + + pub fn notSubsetOfNatural(&self) -> BBoolean { !self.subsetOfNatural() } + + pub fn strictSubsetOfNatural(&self) -> BBoolean { self.subsetOfNatural() } + + pub fn notStrictSubsetOfNatural(&self) -> BBoolean { self.strictSubsetOfNatural() } + + pub fn subsetOfNatural1(&self) -> BBoolean { + if binteger::LOWER_BOUND < 1 { + for idx in 0..BInteger::as_idx(&1) { + if self.arr[idx] { return false; } + } + } + // we could also do self.min() > 0, but that might be slower + return true; + } + + pub fn notSubsetOfNatural1(&self) -> BBoolean { !self.subsetOfNatural1() } + + pub fn strictSubsetOfNatural1(&self) -> BBoolean { self.subsetOfNatural() } + + pub fn notStrictSubsetOfNatural1(&self) -> BBoolean { !self.strictSubsetOfNatural1() } + + pub fn _min(&self) -> BInteger { + for idx in 0..SIZE { + if self.arr[idx] { return BInteger::from_idx(idx); } + } + panic!("Called min on empty Set!"); + } + + pub fn _max(&self) -> BInteger { + for idx in (0..SIZE).rev() { + if self.arr[idx] { return BInteger::from_idx(idx); } + } + panic!("Called max on empty Set!"); + } +} + /* EINT: SetItem<4> + PowSetItem<16, 4> BSet<EINT, 4>: Set<4> + SetItem<16> diff --git a/src/main/java/de/hhu/stups/codegenerator/generators/DeclarationGenerator.java b/src/main/java/de/hhu/stups/codegenerator/generators/DeclarationGenerator.java index f8f0fda997c442a687a5a99995fc1fb40c758288..cfbbdb4953f9ba7a71fe1b662e9d5a56ef63fe84 100644 --- a/src/main/java/de/hhu/stups/codegenerator/generators/DeclarationGenerator.java +++ b/src/main/java/de/hhu/stups/codegenerator/generators/DeclarationGenerator.java @@ -277,6 +277,7 @@ public class DeclarationGenerator { return setDefinitions.getSetDefinitions().map(def -> { if (def.getSetType() instanceof CoupleType) return generateRelationDefinition(def); else if (def.getSetType() instanceof EnumeratedSetElementType) return ""; //TODO? + else if (def.getSetType() instanceof IntegerType) return ""; //TODO? else return generateSetDefinition(def); }).collect(Collectors.toList()); } @@ -314,6 +315,7 @@ public class DeclarationGenerator { if (!this.forEmbedded) return ""; if (type instanceof EnumeratedSetElementType) return ((EnumeratedSetElementType)type).getSetName(); if (type instanceof BoolType) return "BOOL"; //TODO? + if(type instanceof IntegerType) return "BInteger"; SetDefinition setDef = setDefinitions.getDefinition(type); if (setDef == null) { diff --git a/src/main/java/de/hhu/stups/codegenerator/generators/ExpressionGenerator.java b/src/main/java/de/hhu/stups/codegenerator/generators/ExpressionGenerator.java index 24187391a843c20c1357ecaf06654954a270d1f3..97dc1037c0125b112053be9b954f023886cd0a3e 100644 --- a/src/main/java/de/hhu/stups/codegenerator/generators/ExpressionGenerator.java +++ b/src/main/java/de/hhu/stups/codegenerator/generators/ExpressionGenerator.java @@ -524,6 +524,9 @@ public class ExpressionGenerator { return relElementNameGenerator.render(); } } + if (exprNode instanceof NumberNode) { + return ((NumberNode) exprNode).getValue().toString(); + } throw new RuntimeException(String.format("Cannot convert Expression %s to set-element!", exprNode.toString())); } diff --git a/src/main/java/de/hhu/stups/codegenerator/generators/TypeGenerator.java b/src/main/java/de/hhu/stups/codegenerator/generators/TypeGenerator.java index 44e1490feed75d4aeaac7425d2d67af8dd04ac48..dec47465ca50892316a936dfa1ec9a5ad7e1d100 100644 --- a/src/main/java/de/hhu/stups/codegenerator/generators/TypeGenerator.java +++ b/src/main/java/de/hhu/stups/codegenerator/generators/TypeGenerator.java @@ -195,6 +195,11 @@ public class TypeGenerator { EnumeratedSetElementType enumType = (EnumeratedSetElementType) type; variants = enumType.getElements(); name = nameHandler.handleIdentifier(enumType.getSetName(), NameHandler.IdentifierHandlingEnum.FUNCTION_NAMES); + } else if (type instanceof IntegerType) { + variants = new ArrayList<>(); + name = "BInteger"; + // The integer-set is hard-coded into the BType-library (since there isn't a good way of creating it dynamically with generated code) + // Nesting of integer-sets is not supported at all (but the generator won't stop this) } else { throw new RuntimeException("cannot add setDef for type "+type); } @@ -210,22 +215,15 @@ public class TypeGenerator { else if (type instanceof SetType) return getSetVariants((SetType) type); else if (type instanceof CoupleType) return getRelationVariants((CoupleType) type); else if (type instanceof BoolType) return Arrays.asList("BFALSE", "BTRUE"); //TODO: put in template? + else if (type instanceof IntegerType) return new ArrayList<>(); throw new RuntimeException("cannot get Variants for type "+type); } public List<String> getSetVariants(SetType type) { if(!this.setDefinitions.containsDefinition(type)) { - //TODO: try to generate missing set-types on the fly? addSetDefinition(type); - //throw new RuntimeException("Could not find SetDefinition for type "+type); - }/* - ST setElementName = group.getInstanceOf("set_element_name"); - return this.setDefinitions.getDefinition(type).getSubSets().stream().map(subset -> { - setElementName.remove("elements"); - setElementName.add("elements", subset); - return setElementName.render(); - }).collect(Collectors.toList());*/ + } return setDefinitions.getDefinition(type).getElements(); } diff --git a/src/main/resources/de/hhu/stups/codegenerator/RustTemplate_e.stg b/src/main/resources/de/hhu/stups/codegenerator/RustTemplate_e.stg index 5ba037c0917ca192535e9c1980460d98bb9070d1..cc50f3387df5a040a8ff1b5c7ef0b4fe69b692e6 100644 --- a/src/main/resources/de/hhu/stups/codegenerator/RustTemplate_e.stg +++ b/src/main/resources/de/hhu/stups/codegenerator/RustTemplate_e.stg @@ -19,6 +19,7 @@ use btypes::bboolean::BBool; use btypes::bboolean::BOOL; use btypes::binteger::BInteger; use btypes::binteger::BInt; +use btypes::binteger::set_BInteger; <includedMachines; separator="\n"> @@ -578,7 +579,7 @@ mod <machine>; interval(arg1, arg2) ::= << -BSet::\<BInteger>::interval(&<arg1>, &<arg2>) +set_BInteger::interval(&<arg1>, &<arg2>) >> projection(domainType, rangeType, arg1, arg2, isProjection1) ::= << diff --git a/src/test/java/de/hhu/stups/codegenerator/rust_embedded/TestSets.java b/src/test/java/de/hhu/stups/codegenerator/rust_embedded/TestSets.java index 6bf64fbfc5eb80a3b413d352b8784bc05a81055c..57b501e5c9572d91577d80033a0bb8d65908ef16 100644 --- a/src/test/java/de/hhu/stups/codegenerator/rust_embedded/TestSets.java +++ b/src/test/java/de/hhu/stups/codegenerator/rust_embedded/TestSets.java @@ -103,20 +103,17 @@ public class TestSets extends TestRSE { testRSE("GeneralizedIntersectionEmpty", "GeneralizedIntersectionEmptyAddition.strs"); } - - -// These tests won't work, because they require Integer-Sets, which embedded code-gen cannot do (for now) - @Test(expected = RuntimeException.class) + @Test public void testInterval() throws Exception { testRSE("Interval", "IntervalAddition.strs"); } - @Test(expected = RuntimeException.class) + @Test public void testMax() throws Exception { testRSE("Max", "MaxAddition.strs"); } - @Test(expected = RuntimeException.class) + @Test public void testMin() throws Exception { testRSE("Min", "MinAddition.strs"); }