finite closure

This commit is contained in:
Florian Steurer 2015-10-25 11:12:36 +01:00
parent 11fc7a4512
commit 931fb01d74
3 changed files with 80 additions and 8 deletions

View File

@ -1,5 +1,5 @@
package de.dhbwstuttgart.typeinference; package de.dhbwstuttgart.typeinference;
public interface IPair { public interface IPair{
} }

View File

@ -1,13 +1,71 @@
package de.dhbwstuttgart.typinference.unify.model; package de.dhbwstuttgart.typinference.unify.model;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.IPair; import de.dhbwstuttgart.typeinference.Pair.PairOperator;
import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
public class FiniteClosure<T extends IPair> implements IFiniteClosure<T> { public class FiniteClosure<T extends MPair> implements IFiniteClosure<T> {
private HashMap<MType, Node<MType>> inheritanceGraph;
public FiniteClosure(Set<T> pairs) { public FiniteClosure(Set<T> pairs) {
inheritanceGraph = new HashMap<MType, Node<MType>>();
// Build the transitive closure of the inheritance tree
for(T pair : pairs) {
// TODO smaller oder smallerExtends?
if(pair.GetPairOp() != PairOperator.SmallerExtends)
continue;
// Add nodes if not already in the graph
if(!inheritanceGraph.containsKey(pair.GetType1()))
inheritanceGraph.put(pair.GetType1(), new Node<MType>(pair.GetType1()));
if(!inheritanceGraph.containsKey(pair.GetType2()))
inheritanceGraph.put(pair.GetType2(), new Node<MType>(pair.GetType2()));
Node<MType> childNode = inheritanceGraph.get(pair.GetType2());
Node<MType> parentNode = inheritanceGraph.get(pair.GetType1());
// Add edge
parentNode.AddDescendant(childNode);
// Add edges to build the transitive closure
parentNode.getPredecessors().stream().forEach(x -> x.AddDescendant(childNode));
}
}
/**
* Returns all types of the finite closure that are subtypes of the argument.
* @return The set of subtypes of the argument.
*/
public Set<MType> smaller(MType type) {
if(!inheritanceGraph.containsKey(type))
return new HashSet<>();
return inheritanceGraph.get(type).getContentOfDescendants();
}
/**
* Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument.
*/
public Set<MType> greater(MType type) {
if(!inheritanceGraph.containsKey(type))
return new HashSet<>();
return inheritanceGraph.get(type).getContentOfPredecessors();
}
public Set<MType> grArg(MType type) {
throw new NotImplementedException();
}
public Set<MType> smArg(MType type) {
throw new NotImplementedException();
} }
} }

View File

@ -1,9 +1,8 @@
package de.dhbwstuttgart.typinference.unify.model; package de.dhbwstuttgart.typinference.unify.model;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
public class Node<T> { public class Node<T> {
private T content; private T content;
@ -16,10 +15,17 @@ public class Node<T> {
} }
public void AddDescendant(Node<T> descendant) { public void AddDescendant(Node<T> descendant) {
if(descendants.contains(descendant))
return;
descendants.add(descendant); descendants.add(descendant);
descendant.AddPredecessor(this);
} }
public void AddPredecessor(Node<T> predecessor) { public void AddPredecessor(Node<T> predecessor) {
if(predecessors.contains(predecessor))
return;
predecessors.add(predecessor); predecessors.add(predecessor);
predecessor.AddDescendant(this); predecessor.AddDescendant(this);
} }
@ -29,10 +35,18 @@ public class Node<T> {
} }
public Set<Node<T>> getPredecessors() { public Set<Node<T>> getPredecessors() {
return null; return predecessors;
} }
public Set<Node<T>> getDescendants() { public Set<Node<T>> getDescendants() {
return null; return descendants;
}
public Set<T> getContentOfDescendants() {
return descendants.stream().map(x -> x.getContent()).collect(Collectors.toSet());
}
public Set<T> getContentOfPredecessors() {
return predecessors.stream().map(x -> x.getContent()).collect(Collectors.toSet());
} }
} }