blob: 667f850683ff138a66d8bcfe13eb9b3fcf4ad923 [file] [log] [blame]
package org.eclipse.emf.henshin.sam.invcheck;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.henshin.sam.invcheck.adapter.SamGraphInvCheckGraphAdapter;
import org.eclipse.emf.henshin.sam.invcheck.nac.NacFactory;
import org.eclipse.emf.henshin.sam.invcheck.nac.NacPackage;
import org.eclipse.emf.henshin.sam.invcheck.nac.NegativeApplicationCondition;
import org.eclipse.emf.henshin.sam.invcheck.nac.PatternEdge;
import org.eclipse.emf.henshin.sam.invcheck.nac.PatternNode;
import org.eclipse.emf.henshin.sam.model.samannotation.AnnotatedElem;
import org.eclipse.emf.henshin.sam.model.samannotation.Annotation;
import org.eclipse.emf.henshin.sam.model.samgraph.Edge;
import org.eclipse.emf.henshin.sam.model.samgraph.Graph;
import org.eclipse.emf.henshin.sam.model.samgraph.Node;
import org.eclipse.emf.henshin.sam.model.samgraph.SamgraphFactory;
import org.eclipse.emf.henshin.sam.model.samgraph.SamgraphPackage;
import org.eclipse.emf.henshin.sam.model.samgraphcondition.GraphCondition;
import org.eclipse.emf.henshin.sam.model.samgraphcondition.LogicalGCCoupling;
import org.eclipse.emf.henshin.sam.model.samgraphcondition.LogicalOperator;
import org.eclipse.emf.henshin.sam.model.samgraphcondition.NegatedCondition;
import org.eclipse.emf.henshin.sam.model.samgraphcondition.Quantification;
import org.eclipse.emf.henshin.sam.model.samgraphcondition.SamgraphconditionFactory;
import org.eclipse.emf.henshin.sam.model.samgraphcondition.SamgraphconditionPackage;
import org.eclipse.emf.henshin.sam.model.samgraphcondition.TerminationCondition;
import org.eclipse.emf.henshin.sam.model.samrules.SamrulesFactory;
import org.eclipse.emf.henshin.sam.model.samrules.SamrulesPackage;
import org.eclipse.emf.henshin.sam.model.samtrace.Match;
import org.eclipse.emf.henshin.sam.model.samtrace.SamtraceFactory;
import org.eclipse.emf.henshin.sam.model.samtypegraph.EdgeType;
import org.eclipse.emf.henshin.sam.model.samtypegraph.NodeType;
import org.eclipse.emf.henshin.sam.model.samtypegraph.SamtypegraphPackage;
public class InvariantCheckerUtil {
public static PatternNode copyAsPattern(Node n) {
PatternNode result = NacFactory.eINSTANCE.createPatternNode();
result.setInstanceOf(n.getInstanceOf());
result.setName(n.getName());
return result;
}
public static PatternEdge copyAsPattern(Edge e) {
PatternEdge result = NacFactory.eINSTANCE.createPatternEdge();
result.setInstanceOf(e.getInstanceOf());
result.setName(e.getName());
return result;
}
public static GraphCondition createNegatedCondition(NegativeApplicationCondition nac) {
NegatedCondition result = SamgraphconditionFactory.eINSTANCE.createNegatedCondition();
Quantification q = SamgraphconditionFactory.eINSTANCE.createQuantification();
result.setOperand(q);
q.setContext(nacToGraph(nac));
TerminationCondition tC = SamgraphconditionFactory.eINSTANCE.createTerminationCondition();
tC.setIsTrue(true);
q.setNesting(tC);
result.getAnnotations().addAll(nac.getAnnotations());
return result;
}
public static GraphCondition createNegatedConditions(Set<NegativeApplicationCondition> nacs) {
LogicalGCCoupling result = SamgraphconditionFactory.eINSTANCE.createLogicalGCCoupling();
result.setOperator(LogicalOperator.CONJUNCTION);
for (NegativeApplicationCondition nac : nacs) {
result.getOperands().add(createNegatedCondition(nac));
}
return result;
}
public static GraphCondition addNegatedCondition(GraphCondition gc, NegativeApplicationCondition nac) {
if (nac == null) {
return null;
}
if (gc == null) {
return createNegatedCondition(nac);
}
GraphCondition newGC = createNegatedCondition(nac);
if (gc.eClass() == SamgraphconditionPackage.eINSTANCE.getLogicalGCCoupling()) {
((LogicalGCCoupling) gc).getOperands().add(newGC);
return gc;
} else if (gc.eClass() == SamgraphconditionPackage.eINSTANCE.getNegatedCondition()) {
LogicalGCCoupling result = SamgraphconditionFactory.eINSTANCE.createLogicalGCCoupling();
result.setOperator(LogicalOperator.CONJUNCTION);
result.getOperands().add(gc);
result.getOperands().add(newGC);
return result;
} else {
return null;
}
}
public static GraphCondition addNegatedConditions(GraphCondition gc, Set<NegativeApplicationCondition> nacs) {
if (nacs == null) {
return null;
}
if (gc == null) {
return createNegatedConditions(nacs);
}
if (gc.eClass() == SamgraphconditionPackage.eINSTANCE.getLogicalGCCoupling()) {
for (NegativeApplicationCondition nac : nacs) {
GraphCondition newGC = createNegatedCondition(nac);
((LogicalGCCoupling) gc).getOperands().add(newGC);
}
return gc;
} else if (gc.eClass() == SamgraphconditionPackage.eINSTANCE.getNegatedCondition()) {
LogicalGCCoupling result = (LogicalGCCoupling) createNegatedConditions(nacs);
result.setOperator(LogicalOperator.CONJUNCTION);
result.getOperands().add(gc);
return result;
} else {
return null;
}
}
private static Graph nacToGraph(NegativeApplicationCondition nac) {
Graph result = SamgraphFactory.eINSTANCE.createGraph();
/*for (Node n : nac.getNodes()) {
result.getNodes().add(n);
}
for (Edge e : nac.getEdges()) {
result.getEdges().add(e);
}*/
result.getNodes().addAll(nac.getNodes());
result.getEdges().addAll(nac.getEdges());
EcoreUtil.remove(nac);
return result;
}
public static GraphCondition getHighestCondition(AnnotatedElem e) {
Graph g = (Graph) e.eContainer();
EObject result = null;
EObject cont = null;
if (g.eContainer() != null && SamgraphconditionPackage.eINSTANCE.getGraphCondition().isSuperTypeOf(g.eContainer().eClass())) {
cont = g.eContainer();
result = cont;
cont = cont.eContainer();
} else {
return null;
}
while (cont != null) {
if (cont.eClass() == SamgraphconditionPackage.eINSTANCE.getLogicalGCCoupling()) {
return (GraphCondition) result;
} else if (cont.eClass() == SamrulesPackage.eINSTANCE.getRuleGraph()) {
return (GraphCondition) result;
} else if (cont.eClass() == SamtypegraphPackage.eINSTANCE.getTypeGraph()) {
return (GraphCondition) result;
} else {
result = cont;
cont = cont.eContainer();
}
}
return null;
}
public static boolean isNegated(Node n) {
if (n.eContainer().eClass() == NacPackage.eINSTANCE.getNegativeApplicationCondition()) {
return true;
}
GraphCondition gc = getHighestCondition(n);
if (gc == null) {
return false;
}
if (gc.eClass() == SamgraphconditionPackage.eINSTANCE.getNegatedCondition()) {
if (gc.eContainer().eClass() == SamtypegraphPackage.eINSTANCE.getTypeGraph()) {
return false;
} else if (gc.eContainer().eClass() == SamgraphconditionPackage.eINSTANCE.getLogicalGCCoupling()) {
if (gc.eContainer().eContainer().eClass() == SamtypegraphPackage.eINSTANCE.getTypeGraph()) {
return false;
}
}
return true;
} else {
return false;
}
}
public static boolean isNegated(Edge e) {
if (e.eContainer().eClass() == NacPackage.eINSTANCE.getNegativeApplicationCondition()) {
return true;
}
GraphCondition gc = getHighestCondition(e);
if (gc == null) {
return false;
}
if (gc.eClass() == SamgraphconditionPackage.eINSTANCE.getNegatedCondition()) {
if (gc.eContainer().eClass() == SamtypegraphPackage.eINSTANCE.getTypeGraph()) {
return false;
} else if (gc.eContainer().eClass() == SamgraphconditionPackage.eINSTANCE.getLogicalGCCoupling()) {
if (gc.eContainer().eContainer().eClass() == SamtypegraphPackage.eINSTANCE.getTypeGraph()) {
return false;
}
}
return true;
} else {
return false;
}
}
public static int positiveSize(Match matching) {
int count = 0;
for (Edge e : matching.getEdgeMatching().keySet()) {
if (!isNegated(e)) {
count = count + 1;
}
}
for (Node n : matching.getNodeMatching().keySet()) {
if (!isNegated(n)) {
count = count + 1;
}
}
return count;
}
public static Match copyAsRuleGraph(Graph g) {
Match currentMatching = SamtraceFactory.eINSTANCE.createMatch();
Graph result = SamrulesFactory.eINSTANCE.createRuleGraph();
result.setTypedOver(g.getTypedOver());
for (Node n : g.getNodes()) {
Node newNode = copyAsPattern(n);
if (n.eClass() == NacPackage.eINSTANCE.getPatternNode()) {
((PatternNode) newNode).setSameInProp(((PatternNode) n).getSameInProp());
((PatternNode) newNode).setSameInRule(((PatternNode) n).getSameInRule());
}
currentMatching.getNodeMatching().put(n, newNode);
result.getNodes().add(newNode);
}
for (Edge e : g.getEdges()) {
Edge newEdge = copyAsPattern(e);
if (e.eClass() == NacPackage.eINSTANCE.getPatternEdge()) {
((PatternEdge) newEdge).setSameInProp(((PatternEdge) e).getSameInProp());
((PatternEdge) newEdge).setSameInRule(((PatternEdge) e).getSameInRule());
}
currentMatching.getEdgeMatching().put(e, newEdge);
newEdge.setSource(currentMatching.getNodeMatching().get(e.getSource()));
newEdge.setTarget(currentMatching.getNodeMatching().get(e.getTarget()));
result.getEdges().add(newEdge);
}
return currentMatching;
}
public static Match createMinimalTranslation(Graph graph, Match matching) {
Match resultMatching = SamtraceFactory.eINSTANCE.createMatch();
Graph result = SamrulesFactory.eINSTANCE.createRuleGraph();
for (Node src : matching.getNodeMatching().values()) {
if (!graph.getNodes().contains(src)) {
throw new RuntimeException("something strange happened");
}
Node n = src.copy();
result.getNodes().add(n);
resultMatching.getNodeMatching().put(src, n);
}
for (Edge src : matching.getEdgeMatching().values()) {
if (!graph.getEdges().contains(src)) {
throw new RuntimeException("something strange happened");
}
Edge e = src.copy();
e.setSource(resultMatching.getNodeMatching().get(src.getSource()));
e.setTarget(resultMatching.getNodeMatching().get(src.getTarget()));
result.getEdges().add(e);
resultMatching.getEdgeMatching().put(src, e);
}
for (NegativeApplicationCondition nac : SamGraphInvCheckGraphAdapter.getInstance(graph).getNacs()) {
for (Annotation an : nac.getAnnotations()) {
if (an.getSource().equals(InvariantCheckerPlugin.NAC_BOUND_ITEM)) {
if (!graph.getNodes().contains(an.getTarget()) && !graph.getEdges().contains(an.getTarget())) {
throw new RuntimeException("something strange happened");
}
if (SamgraphPackage.eINSTANCE.getNode().isSuperTypeOf(an.getTarget().eClass())) {
if (!resultMatching.getNodeMatching().containsKey(an.getTarget())) {
Node n = ((Node) an.getTarget()).copy();
result.getNodes().add(n);
resultMatching.getNodeMatching().put((Node) an.getTarget(), n);
}
}
}
}
for (Annotation an : nac.getAnnotations()) {
if (an.getSource().equals(InvariantCheckerPlugin.NAC_BOUND_ITEM)) {
if (!graph.getNodes().contains(an.getTarget()) && !graph.getEdges().contains(an.getTarget())) {
throw new RuntimeException("something strange happened");
}
if (SamgraphPackage.eINSTANCE.getEdge().isSuperTypeOf(an.getTarget().eClass())) {
if (!resultMatching.getEdgeMatching().containsKey(an.getTarget())) {
Edge e = ((Edge) an.getTarget()).copy();
e.setSource(resultMatching.getNodeMatching().get(((Edge) an.getTarget()).getSource()));
e.setTarget(resultMatching.getNodeMatching().get(((Edge) an.getTarget()).getTarget()));
result.getEdges().add(e);
resultMatching.getEdgeMatching().put((Edge) an.getTarget(), e);
}
}
}
}
}
return resultMatching;
}
public static Map<NodeType, Integer> calculateNodeTypeCount(Graph hostGraph) {
Map<NodeType, Integer> result = new HashMap<NodeType, Integer>();
if (hostGraph == null) {
return result;
}
for (Node n : hostGraph.getNodes()) {
NodeType type = n.getInstanceOf();
if (result.containsKey(type)) {
result.put(type, result.get(type) + 1);
} else {
result.put(type, 1);
}
}
return result;
}
public static Map<EdgeType, Integer> calculateEdgeTypeCount(Graph hostGraph) {
Map<EdgeType, Integer> result = new HashMap<EdgeType, Integer>();
if (hostGraph == null) {
return result;
}
for (Edge e : hostGraph.getEdges()) {
EdgeType type = e.getInstanceOf();
if (result.containsKey(type)) {
result.put(type, result.get(type) + 1);
} else {
result.put(type, 1);
}
}
return result;
}
}