Cartesian product as Stream
This commit is contained in:
parent
2f37bb7313
commit
0dc8a53fca
8
pom.xml
8
pom.xml
@ -118,6 +118,14 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
|
@ -6,6 +6,7 @@ import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
//TODO: Remove this class
|
||||
public class Constraint<A> extends HashSet<A> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Boolean isInherited = false;//wird nur für die Method-Constraints benoetigt
|
||||
|
@ -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<OderConstraint> oderConstraints = new HashSet<>();
|
||||
|
||||
public ConstraintSet2(Set<OderConstraint> constraints){
|
||||
if(constraints.isEmpty())throw new RuntimeException("Empty constraint set");
|
||||
this.oderConstraints = constraints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
BinaryOperator<String> b = (x,y) -> x+y;
|
||||
return "ODER:" + this.oderConstraints.stream().reduce("", (x,y) -> x.toString()+ "\n" +y, b);
|
||||
}
|
||||
|
||||
private class ConstraintSpliterator implements Spliterator<Set<Pair>> {
|
||||
private List<OderConstraint> constraints;
|
||||
private long i = 0;
|
||||
private long max = 0;
|
||||
private List<Integer> sizes;
|
||||
private List<Long> bases = new ArrayList<>();
|
||||
|
||||
ConstraintSpliterator(List<OderConstraint> 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<OderConstraint> constraints, long start, long end){
|
||||
this(constraints);
|
||||
i = start;
|
||||
max = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super Set<Pair>> consumer) {
|
||||
if(i > max) return false;
|
||||
consumer.accept(get(i));
|
||||
i++;
|
||||
return true;
|
||||
}
|
||||
|
||||
private Set<Pair> get(long num){
|
||||
Set<Pair> ret = new HashSet<>();
|
||||
Iterator<Long> baseIt = bases.iterator();
|
||||
for(OderConstraint constraint : constraints){
|
||||
ret.addAll(constraint.get((int) ((num/baseIt.next())%constraint.getSize())));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<Set<Pair>> 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<Set<Pair>> cartesianProductParallel(){
|
||||
return StreamSupport.stream(new ConstraintSpliterator(oderConstraints.stream().collect(Collectors.toList())), true);
|
||||
}
|
||||
/*
|
||||
public Map<String, TypePlaceholder> generateTPHMap() {
|
||||
HashMap<String, TypePlaceholder> 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;
|
||||
}
|
||||
*/
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package de.dhbwstuttgart.typeinference.constraints;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class ConstraintSetBuilder {
|
||||
private Set<Pair> undConstraints = new HashSet<>();
|
||||
private Set<OderConstraint> 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);
|
||||
}
|
||||
}
|
@ -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<Set<Pair>> cons;
|
||||
public OderConstraint(Set<Set<Pair>> orCons){
|
||||
if(orCons.isEmpty())throw new RuntimeException("Empty constraint set");
|
||||
for(Set<Pair> 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<Pair> get(int l) {
|
||||
return cons.get(l);
|
||||
}
|
||||
}
|
62
src/test/java/typeinference/ConstraintSetTests.java
Normal file
62
src/test/java/typeinference/ConstraintSetTests.java
Normal file
@ -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<Set<Pair>> 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<Set<Pair>> 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<Set<Pair>> 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<Set<Pair>> 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<Set<Pair>> 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()));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user