diff --git a/pom.xml b/pom.xml
index 95b20386..bb00efae 100644
--- a/pom.xml
+++ b/pom.xml
@@ -118,7 +118,15 @@ http://maven.apache.org/maven-v4_0_0.xsd">
-
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 9
+
+
+
diff --git a/src/main/java/de/dhbwstuttgart/typeinference/constraints/Constraint.java b/src/main/java/de/dhbwstuttgart/typeinference/constraints/Constraint.java
index 8715fe55..cbd5c8fa 100644
--- a/src/main/java/de/dhbwstuttgart/typeinference/constraints/Constraint.java
+++ b/src/main/java/de/dhbwstuttgart/typeinference/constraints/Constraint.java
@@ -6,6 +6,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
+//TODO: Remove this class
public class Constraint extends HashSet {
private static final long serialVersionUID = 1L;
private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt
diff --git a/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet2.java b/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet2.java
new file mode 100644
index 00000000..ded3ecfb
--- /dev/null
+++ b/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSet2.java
@@ -0,0 +1,107 @@
+package de.dhbwstuttgart.typeinference.constraints;
+
+
+import java.util.*;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+public class ConstraintSet2 {
+ Set oderConstraints = new HashSet<>();
+
+ public ConstraintSet2(Set constraints){
+ if(constraints.isEmpty())throw new RuntimeException("Empty constraint set");
+ this.oderConstraints = constraints;
+ }
+
+ @Override
+ public String toString(){
+ BinaryOperator b = (x,y) -> x+y;
+ return "ODER:" + this.oderConstraints.stream().reduce("", (x,y) -> x.toString()+ "\n" +y, b);
+ }
+
+ private class ConstraintSpliterator implements Spliterator> {
+ private List constraints;
+ private long i = 0;
+ private long max = 0;
+ private List sizes;
+ private List bases = new ArrayList<>();
+
+ ConstraintSpliterator(List constraints){
+ this.constraints = constraints;
+ sizes = constraints.stream().map(OderConstraint::getSize).collect(Collectors.toList());
+ long base = 1;
+ for(int size : sizes){
+ bases.add(base);
+ base *= size;
+ }
+ i = 0;
+ max = estimateSize() - 1;
+ }
+
+ ConstraintSpliterator(List constraints, long start, long end){
+ this(constraints);
+ i = start;
+ max = end;
+ }
+
+ @Override
+ public boolean tryAdvance(Consumer super Set> consumer) {
+ if(i > max) return false;
+ consumer.accept(get(i));
+ i++;
+ return true;
+ }
+
+ private Set get(long num){
+ Set ret = new HashSet<>();
+ Iterator baseIt = bases.iterator();
+ for(OderConstraint constraint : constraints){
+ ret.addAll(constraint.get((int) ((num/baseIt.next())%constraint.getSize())));
+ }
+ return ret;
+ }
+
+ @Override
+ public Spliterator> trySplit() {
+ if(max - i < 2) return null;
+ long middle = i + ((max- i) / 2);
+ long maxOld = max;
+ max = middle - 1;
+ return new ConstraintSpliterator(constraints, middle, maxOld);
+ }
+
+ @Override
+ public long estimateSize() {
+ long ret = 1;
+ for (int size : sizes)ret*=size;
+ return ret;
+ }
+
+ @Override
+ public int characteristics() {
+ return ORDERED | SIZED | IMMUTABLE | NONNULL;
+ }
+ }
+
+ public Stream> cartesianProductParallel(){
+ return StreamSupport.stream(new ConstraintSpliterator(oderConstraints.stream().collect(Collectors.toList())), true);
+ }
+/*
+ public Map generateTPHMap() {
+ HashMap ret = new HashMap<>();
+ constraints.map((Pair p) -> {
+ if (p.TA1 instanceof TypePlaceholder) {
+ ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1);
+ }
+ if (p.TA2 instanceof TypePlaceholder) {
+ ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2);
+ }
+ return null;
+ });
+ return ret;
+ }
+*/
+}
diff --git a/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSetBuilder.java b/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSetBuilder.java
new file mode 100644
index 00000000..377e2214
--- /dev/null
+++ b/src/main/java/de/dhbwstuttgart/typeinference/constraints/ConstraintSetBuilder.java
@@ -0,0 +1,26 @@
+package de.dhbwstuttgart.typeinference.constraints;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class ConstraintSetBuilder {
+ private Set undConstraints = new HashSet<>();
+ private Set oderConstraints = new HashSet<>();
+ private boolean done = false;
+
+ public void addUndConstraint(Pair p){
+ undConstraints.add(p);
+ }
+
+ public void addOderConstraint(OderConstraint orConstraint) {
+ oderConstraints.add(orConstraint);
+ }
+
+ public ConstraintSet2 build(){
+ if(done)throw new RuntimeException("Trying to build cartesian product twice");
+ this.done = true;
+ if(!undConstraints.isEmpty())
+ oderConstraints.add(new OderConstraint(Set.of(undConstraints)));
+ return new ConstraintSet2(oderConstraints);
+ }
+}
diff --git a/src/main/java/de/dhbwstuttgart/typeinference/constraints/OderConstraint.java b/src/main/java/de/dhbwstuttgart/typeinference/constraints/OderConstraint.java
new file mode 100644
index 00000000..70d880c1
--- /dev/null
+++ b/src/main/java/de/dhbwstuttgart/typeinference/constraints/OderConstraint.java
@@ -0,0 +1,24 @@
+package de.dhbwstuttgart.typeinference.constraints;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class OderConstraint {
+ private final List> cons;
+ public OderConstraint(Set> orCons){
+ if(orCons.isEmpty())throw new RuntimeException("Empty constraint set");
+ for(Set c : orCons){
+ if(c.isEmpty())throw new RuntimeException("Empty constraint set");
+ }
+ this.cons = orCons.stream().collect(Collectors.toList());
+ }
+
+ public int getSize(){
+ return cons.size();
+ }
+
+ public Set get(int l) {
+ return cons.get(l);
+ }
+}
diff --git a/src/test/java/typeinference/ConstraintSetTests.java b/src/test/java/typeinference/ConstraintSetTests.java
new file mode 100644
index 00000000..99863c8e
--- /dev/null
+++ b/src/test/java/typeinference/ConstraintSetTests.java
@@ -0,0 +1,62 @@
+package typeinference;
+
+import de.dhbwstuttgart.parser.NullToken;
+import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
+import de.dhbwstuttgart.typeinference.constraints.ConstraintSetBuilder;
+import de.dhbwstuttgart.typeinference.constraints.OderConstraint;
+import de.dhbwstuttgart.typeinference.constraints.Pair;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class ConstraintSetTests {
+ @Test
+ public void cartesianProductTestSingleConstraint(){
+ ConstraintSetBuilder builder = new ConstraintSetBuilder();
+ builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()))));
+ List> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
+ assert result.size() == 1;
+ }
+
+ @Test
+ public void cartesianProductTestSingleOderConstraint(){
+ ConstraintSetBuilder builder = new ConstraintSetBuilder();
+ builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
+ List> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
+ assert result.size() == 2;
+ }
+
+ @Test
+ public void cartesianProductTestTwoOderConstraint(){
+ ConstraintSetBuilder builder = new ConstraintSetBuilder();
+ builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
+ builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
+ List> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
+ assert result.size() == 4;
+ }
+
+ @Test
+ public void cartesianProductTestThreeOderConstraint(){
+ ConstraintSetBuilder builder = new ConstraintSetBuilder();
+ builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
+ builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
+ builder.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()))));
+ List> result = builder.build().cartesianProductParallel().collect(Collectors.toList());
+ assert result.size() == 4;
+
+ ConstraintSetBuilder builder2 = new ConstraintSetBuilder();
+ builder2.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
+ builder2.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
+ builder2.addOderConstraint(new OderConstraint(Set.of(Set.of(generatePair()), Set.of(generatePair()))));
+ List> result2 = builder2.build().cartesianProductParallel().collect(Collectors.toList());
+
+ assert result2.stream().map( a -> a.stream().map(p -> p.TA1.toString()).reduce("", (x, y)-> x+" "+y)).collect(Collectors.toSet()).size() == 8;
+ assert result2.size() == 8;
+ }
+
+ public Pair generatePair(){
+ return new Pair(TypePlaceholder.fresh(new NullToken()), TypePlaceholder.fresh(new NullToken()));
+ }
+}