package org.eclipse.emf.henshin.model.staticanalysis;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Set;
import org.eclipse.emf.henshin.model.Edge;
import org.eclipse.emf.henshin.model.Graph;
import org.eclipse.emf.henshin.model.Node;
public class NodeMap extends LinkedHashMap<Node,Node> {
private static final long serialVersionUID = 1L;
private final Graph source;
private final Graph target;
public NodeMap(Graph source, Graph target) {
this.source = source;
this.target = target;
}
public boolean isTotal() {
return source.getNodes().size() == keySet().size() &&
keySet().containsAll(source.getNodes());
}
public boolean isInjective() {
Set<Node> images = new HashSet<Node>();
for (Node origin : keySet()) {
if (!images.add(get(origin))) return false;
}
return true;
}
public boolean isSurjective() {
return target.getNodes().size() == values().size() &&
values().containsAll(target.getNodes());
}
public boolean isBijective() {
return isTotal() && isInjective() && isSurjective();
}
public boolean isGraphMorphism() {
// Check node types:
for (Node origin : keySet()) {
if (origin.getType()!=get(origin).getType()) return false;
}
// Check edges:
for (Edge edge : source.getEdges()) {
Node srcImage = get(edge.getSource());
Node trgImage = get(edge.getTarget());
if (srcImage!=null && trgImage!=null) {
if (srcImage.getOutgoing(edge.getType(), trgImage)==null) {
return false;
}
}
}
return true;
}
public NodeMap getInverse() throws Exception {
if (!isInjective()) {
throw new RuntimeException("Cannot invert non-injective graph morphism");
}
NodeMap inverse = new NodeMap(target, source);
for (Node origin : keySet()) {
inverse.put(get(origin), origin);
}
return inverse;
}
}