blob: 7350c0be0d3db681cd947288092edb89faa5c3b2 [file] [log] [blame]
package org.eclipse.emf.henshin.sam.invcheck.algorithm;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.henshin.sam.invcheck.InvariantCheckerPlugin;
import org.eclipse.emf.henshin.sam.invcheck.InvariantCheckerUtil;
import org.eclipse.emf.henshin.sam.invcheck.SubgraphIterator;
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.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.samannotation.SamannotationFactory;
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.SamgraphPackage;
import org.eclipse.emf.henshin.sam.model.samrules.GraphRule;
import org.eclipse.emf.henshin.sam.model.samrules.PreservedEdge;
import org.eclipse.emf.henshin.sam.model.samrules.PreservedNode;
import org.eclipse.emf.henshin.sam.model.samrules.RuleGraph;
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;
/**
* Reversely applies a graph rule to a graph (typically a target graph pattern)
* to build the source graph (typically a source graph pattern). When
* (reversely) applying the rule, NACs from the left side of the rule and NACs
* from the target (typically a target graph pattern) are copied to the result.
*
* The following diagram shows the behaviour of the reverseRuleApplication
* method.
*
* <p>
* <img src="../../../../../doc/diagrams/ruleApplication.png" alt=
* "Rule application">
* </p>
*
*/
public class RuleApplication implements AlgorithmComponent {
// note: rhs map is sgp -> rhs, lhs map is lhs -> sgp, tgp map is tgp -> sgp
// or the reverse for forwardRuleApplication
private Map<Graph, Map<AnnotatedElem, AnnotatedElem>> refItems = new HashMap<Graph, Map<AnnotatedElem, AnnotatedElem>>();
/**
* Applies a graphRule or GraphTransformation to a Graph. The rule is
* applied reversly, this means from the right hand to the left hand side.
* But you can use this method also to apply a rule in the "correct" way:
* just switch right and left hand side of the graphrule.
*
* @param r
* the graphrule to apply
* @param srcGraph
* No description provided
* @return g after apllying rule or null if at least one parameter is null
* or the rule is not applicable using the restricted spo
*/
public Graph reverseRuleApplication(final Graph srcGraph, final GraphRule r) {
refItems.put(srcGraph, new HashMap<AnnotatedElem, AnnotatedElem>());
if (srcGraph != null && r != null) {
Graph rhs = r.getRight();
Graph lhs = r.getLeft();
refItems.put(lhs, new HashMap<AnnotatedElem, AnnotatedElem>());
refItems.put(rhs, new HashMap<AnnotatedElem, AnnotatedElem>());
RuleGraph g = this.copyGraph(srcGraph, r, false);
// remove all nodes and edges from g, that are created by the rule
for (Iterator<Node> iter = g.getNodes().iterator(); iter.hasNext();) {
Node node = iter.next();
boolean isInRightRuleSide = refItems.get(rhs).get(node) != null;
boolean isInBothRuleSides = isInRightRuleSide
&& refItems.get(rhs).get(node).eClass() == SamrulesPackage.eINSTANCE.getPreservedNode();
if (isInRightRuleSide && !isInBothRuleSides) {
boolean deleteIt = true;
for (Iterator<Edge> i = node.getOutgoing().iterator(); i.hasNext() && deleteIt;) {
Edge e = i.next();
if (refItems.get(rhs).get(e) == null) {
deleteIt = false;
}
}
for (Iterator<Edge> i = node.getIncoming().iterator(); i.hasNext() && deleteIt;) {
Edge e = i.next();
if (refItems.get(rhs).get(e) == null) {
deleteIt = false;
}
}
if (deleteIt) {
// actually I think the items have to be removed from
// refItems as well,
// especially from refItems.get(tgp); unfortunately we
// have to do an inverse
// lookup
Node key = null; // TODO find a better way to remove
// obsolete items
for (Map.Entry<AnnotatedElem, AnnotatedElem> entry : refItems.get(srcGraph).entrySet()) {
if (entry.getValue() == node) {
key = (Node) entry.getKey();
break;
}
}
refItems.get(srcGraph).remove(key);
refItems.get(lhs).remove(((PatternNode) node).getSameInRule());
refItems.get(rhs).remove(node);
node.getIncoming().clear();
node.getOutgoing().clear();
((PatternNode) node).setSameInRule(null);
((PatternNode) node).setSameInProp(null); // manage
// origin of
// elements
// in sgp
iter.remove();
} else {
return null;
}
} else if (isInBothRuleSides) {
refItems.get(lhs).put(((PreservedNode) refItems.get(rhs).get(node)).getRefInRule(), node);
}
}
for (Iterator<Edge> iter = g.getEdges().iterator(); iter.hasNext();) {
Edge edge = iter.next();
boolean isInRightRuleSide = refItems.get(rhs).get(edge) != null;
boolean isInBothRuleSides = isInRightRuleSide
&& refItems.get(rhs).get(edge).eClass() == SamrulesPackage.eINSTANCE.getPreservedEdge();
if (isInRightRuleSide && !isInBothRuleSides) {
Edge key = null; // TODO find a better way to remove
// obsolete items
for (Map.Entry<AnnotatedElem, AnnotatedElem> entry : refItems.get(srcGraph).entrySet()) {
if (entry.getValue() == edge) {
key = (Edge) entry.getKey();
break;
}
}
refItems.get(srcGraph).remove(key);
refItems.get(lhs).remove(((PatternEdge) edge).getSameInRule());
refItems.get(rhs).remove(edge);
edge.setSource(null);
edge.setTarget(null);
((PatternEdge) edge).setSameInRule(null);
((PatternEdge) edge).setSameInProp(null); // manage origin
// of elements
// in dgp
iter.remove();
} else if (isInBothRuleSides) {
refItems.get(lhs).put(((PreservedEdge) refItems.get(rhs).get(edge)).getRefInRule(), edge);
}
}
// add the nodes and edges deleted by the rule to g
for (Iterator<Node> iter = lhs.getNodes().iterator(); iter.hasNext();) {
Node node = iter.next();
boolean isDeleted = node.eClass() != SamrulesPackage.eINSTANCE.getPreservedNode()
|| ((PreservedNode) node).getRefInRule() == null;
if (isDeleted) {
Node newNode = InvariantCheckerUtil.copyAsPattern(node);// node.copy();
g.getNodes().add(newNode);
// node.addToReferenceItems (newNode);
((PatternNode) newNode).setSameInRule(node);
refItems.get(lhs).put(node, newNode);
}
}
for (Iterator<Edge> iter = lhs.getEdges().iterator(); iter.hasNext();) {
Edge edge = iter.next();
boolean isDeleted = edge.eClass() != SamrulesPackage.eINSTANCE.getPreservedEdge()
|| ((PreservedEdge) edge).getRefInRule() == null;
if (isDeleted) {
Edge newEdge = InvariantCheckerUtil.copyAsPattern(edge);// edge.copy();
g.getEdges().add(newEdge);
((PatternEdge) newEdge).setSameInRule(edge);
refItems.get(lhs).put(edge, newEdge);
}
}
// ensure that assocs in g are isomorph to lhs
createAssocs(lhs, g);
// translate NACs from the left rule side to the source graph
NACTranslator nacT = new NACTranslator();
Match initialMatching = SamtraceFactory.eINSTANCE.createMatch();
nacT.setMergedGraph(g);
nacT.setPattern(lhs);
for (Map.Entry<AnnotatedElem, AnnotatedElem> entry : refItems.get(lhs).entrySet()) {
if (SamgraphPackage.eINSTANCE.getNode().isSuperTypeOf(entry.getKey().eClass())) {
initialMatching.getNodeMatching().put((Node) entry.getKey(), (Node) entry.getValue());
} else {
initialMatching.getEdgeMatching().put((Edge) entry.getKey(), (Edge) entry.getValue());
}
}
nacT.setInitialMatching(initialMatching);
g = nacT.translate();
if (g == null) {
// one or more nacs could not be translated because they were
// found as positive elements
// rule is not applicable
return null;
}
Set<NegativeApplicationCondition> newNacs = new HashSet<NegativeApplicationCondition>();
// copy NACs from the target graph pattern
for (NegativeApplicationCondition nac : SamGraphInvCheckGraphAdapter.getInstance(srcGraph).getNacs()) {
boolean consistent = true;
Match currentMatching = SamtraceFactory.eINSTANCE.createMatch();
for (Edge e : nac.getEdges()) {
// boolean found = false;
// if (e.partOfNacInterface() && !e.getSource().isNegated())
// {
if (e.partOfNacInterface() && !InvariantCheckerUtil.isNegated(e.getSource())) {
if (refItems.get(srcGraph).get(e.getSource()) == null) {
consistent = false;
} else {
currentMatching.getNodeMatching().put(e.getSource(),
(Node) refItems.get(srcGraph).get(e.getSource()));
}
}
if (e.partOfNacInterface() && !InvariantCheckerUtil.isNegated(e.getTarget())) {
if (refItems.get(srcGraph).get(e.getTarget()) == null) {
consistent = false;
} else {
currentMatching.getNodeMatching().put(e.getTarget(),
(Node) refItems.get(srcGraph).get(e.getTarget()));
}
}
}
if (consistent) {
NegativeApplicationCondition newNac = NacFactory.eINSTANCE.createNegativeApplicationCondition();
for (Node n : nac.getNodes()) {
// Node newNode = n.copy();
Node newNode = InvariantCheckerUtil.copyAsPattern(n);
((PatternNode) newNode).setSameInProp(((PatternNode) n).getSameInProp());
newNac.getNodes().add(newNode);
currentMatching.getNodeMatching().put(n, newNode);
}
for (Edge e : nac.getEdges()) {
// Edge newEdge = e.copy();
Edge newEdge = InvariantCheckerUtil.copyAsPattern(e);
((PatternEdge) newEdge).setSameInProp(((PatternEdge) e).getSameInProp());
newNac.getEdges().add(newEdge);
newEdge.setSource(currentMatching.getNodeMatching().get(e.getSource()));
newEdge.setTarget(currentMatching.getNodeMatching().get(e.getTarget()));
}
for (Annotation an : nac.getAnnotations()) {
if (refItems.get(srcGraph).get(an.getTarget()) != null) {
Annotation anCopy = SamannotationFactory.eINSTANCE.createAnnotation();
anCopy.setSource(an.getSource());
anCopy.setTarget(refItems.get(srcGraph).get(an.getTarget()));
newNac.getAnnotations().add(anCopy);
}
}
for (Node n : lhs.getNodes()) {
if (SamrulesPackage.eINSTANCE.getDeletedNode() == n.eClass()) {
Node copyInSgp = (Node) refItems.get(lhs).get(n);
Annotation an = SamannotationFactory.eINSTANCE.createAnnotation();
an.setSource(InvariantCheckerPlugin.NAC_BOUND_ITEM);
an.setTarget(copyInSgp);
newNac.getAnnotations().add(an);
}
}
for (Edge e : lhs.getEdges()) {
if (SamrulesPackage.eINSTANCE.getDeletedEdge() == e.eClass()) {
Edge copyInSgp = (Edge) refItems.get(lhs).get(e);
Annotation an = SamannotationFactory.eINSTANCE.createAnnotation();
an.setSource(InvariantCheckerPlugin.NAC_BOUND_ITEM);
an.setTarget(copyInSgp);
newNac.getAnnotations().add(an);
}
}
newNacs.add(newNac);
}
}
if (!newNacs.isEmpty()) {
g.setCondition(InvariantCheckerUtil.addNegatedConditions(g.getCondition(), newNacs));
}
return g;
}
return null;
} // end of reverseRuleApplication()
public Graph forwardRuleApplication(final Graph srcGraph, final GraphRule r) {
refItems.put(srcGraph, new HashMap<AnnotatedElem, AnnotatedElem>());
if (srcGraph != null && r != null) {
Graph rhs = r.getRight();
Graph lhs = r.getLeft();
// first step: translate NACs from the left rule side to the source
// pattern
NACTranslator nacT = new NACTranslator();
Match initialMatching = SamtraceFactory.eINSTANCE.createMatch();
nacT.setMergedGraph((RuleGraph) srcGraph);
nacT.setPattern(lhs);
for (Node n : srcGraph.getNodes()) {
if (((PatternNode) n).getSameInRule() != null) {
initialMatching.getNodeMatching().put(((PatternNode) n).getSameInRule(), n);
}
}
for (Edge e : srcGraph.getEdges()) {
if (((PatternEdge) e).getSameInRule() != null) {
initialMatching.getEdgeMatching().put(((PatternEdge) e).getSameInRule(), e);
}
}
nacT.setInitialMatching(initialMatching);
Graph res = nacT.translate();
if (res == null) {
// one or more nacs could not be translated because they were
// found as positive elements
// rule is not applicable
return null;
}
refItems.put(lhs, new HashMap<AnnotatedElem, AnnotatedElem>());
refItems.put(rhs, new HashMap<AnnotatedElem, AnnotatedElem>());
RuleGraph g = this.copyGraph(srcGraph, r, true);
// remove all nodes and edges from g, that are deleted by the rule
for (Iterator<Node> iter = g.getNodes().iterator(); iter.hasNext();) {
Node node = iter.next();
boolean isInLeftRuleSide = refItems.get(lhs).get(node) != null;
boolean isInBothRuleSides = isInLeftRuleSide
&& refItems.get(lhs).get(node).eClass() == SamrulesPackage.eINSTANCE.getPreservedNode();
if (isInLeftRuleSide && !isInBothRuleSides) {
boolean deleteIt = true;
for (Iterator<Edge> i = node.getOutgoing().iterator(); i.hasNext() && deleteIt;) {
Edge e = i.next();
if (refItems.get(lhs).get(e) == null) {
deleteIt = false;
}
}
for (Iterator<Edge> i = node.getIncoming().iterator(); i.hasNext() && deleteIt;) {
Edge e = i.next();
if (refItems.get(lhs).get(e) == null) {
deleteIt = false;
}
}
if (deleteIt) {
// actually I think the items have to be removed from
// refItems as well,
// especially from refItems.get(tgp); unfortunately we
// have to do an inverse
// lookup
Node key = null; // TODO find a better way to remove
// obsolete items
for (Map.Entry<AnnotatedElem, AnnotatedElem> entry : refItems.get(srcGraph).entrySet()) {
if (entry.getValue() == node) {
key = (Node) entry.getKey();
break;
}
}
refItems.get(srcGraph).remove(key);
refItems.get(rhs).remove(((PatternNode) node).getSameInRule());
refItems.get(lhs).remove(node);
node.getIncoming().clear();
node.getOutgoing().clear();
((PatternNode) node).setSameInRule(null);
((PatternNode) node).setSameInProp(null); // manage
// origin of
// elements
// in tgp
iter.remove();
} else {
System.out.println(node);
return null;
}
} else if (isInBothRuleSides) {
refItems.get(rhs).put(((PreservedNode) refItems.get(lhs).get(node)).getRefInRule(), node);
}
}
for (Iterator<Edge> iter = g.getEdges().iterator(); iter.hasNext();) {
Edge edge = iter.next();
boolean isInLeftRuleSide = refItems.get(lhs).get(edge) != null;
boolean isInBothRuleSides = isInLeftRuleSide
&& refItems.get(lhs).get(edge).eClass() == SamrulesPackage.eINSTANCE.getPreservedEdge();
if (isInLeftRuleSide && !isInBothRuleSides) {
Edge key = null; // TODO find a better way to remove
// obsolete items
for (Map.Entry<AnnotatedElem, AnnotatedElem> entry : refItems.get(srcGraph).entrySet()) {
if (entry.getValue() == edge) {
key = (Edge) entry.getKey();
break;
}
}
refItems.get(srcGraph).remove(key);
refItems.get(rhs).remove(((PatternEdge) edge).getSameInRule());
refItems.get(lhs).remove(edge);
edge.setSource(null);
edge.setTarget(null);
((PatternEdge) edge).setSameInRule(null);
((PatternEdge) edge).setSameInProp(null); // manage origin
// of elements
// in tgp
iter.remove();
} else if (isInBothRuleSides) {
refItems.get(rhs).put(((PreservedEdge) refItems.get(lhs).get(edge)).getRefInRule(), edge);
}
}
// add the nodes and edges created by the rule to g
for (Iterator<Node> iter = rhs.getNodes().iterator(); iter.hasNext();) {
Node node = iter.next();
boolean isCreated = node.eClass() != SamrulesPackage.eINSTANCE.getPreservedNode()
|| ((PreservedNode) node).getRefInRule() == null;
if (isCreated) {
Node newNode = InvariantCheckerUtil.copyAsPattern(node);// node.copy();
g.getNodes().add(newNode);
// node.addToReferenceItems (newNode);
((PatternNode) newNode).setSameInRule(node);
refItems.get(rhs).put(node, newNode);
}
}
for (Iterator<Edge> iter = rhs.getEdges().iterator(); iter.hasNext();) {
Edge edge = iter.next();
boolean isCreated = edge.eClass() != SamrulesPackage.eINSTANCE.getPreservedEdge()
|| ((PreservedEdge) edge).getRefInRule() == null;
if (isCreated) {
Edge newEdge = InvariantCheckerUtil.copyAsPattern(edge);// edge.copy();
g.getEdges().add(newEdge);
((PatternEdge) newEdge).setSameInRule(edge);
refItems.get(rhs).put(edge, newEdge);
}
}
// ensure that assocs in g are isomorph to rhs
createAssocs(rhs, g);
Set<NegativeApplicationCondition> newNacs = new HashSet<NegativeApplicationCondition>();
// copy all applicable NACs from the source graph pattern to the
// target graph pattern
for (NegativeApplicationCondition nac : SamGraphInvCheckGraphAdapter.getInstance(srcGraph).getNacs()) {
boolean consistent = true;
Match currentMatching = SamtraceFactory.eINSTANCE.createMatch();
for (Edge e : nac.getEdges()) {
// boolean found = false;
// if (e.partOfNacInterface() && !e.getSource().isNegated())
// {
if (e.partOfNacInterface() && !InvariantCheckerUtil.isNegated(e.getSource())) {
if (refItems.get(srcGraph).get(e.getSource()) == null) {
consistent = false;
} else {
currentMatching.getNodeMatching().put(e.getSource(),
(Node) refItems.get(srcGraph).get(e.getSource()));
}
}
if (e.partOfNacInterface() && !InvariantCheckerUtil.isNegated(e.getTarget())) {
if (refItems.get(srcGraph).get(e.getTarget()) == null) {
consistent = false;
} else {
currentMatching.getNodeMatching().put(e.getTarget(),
(Node) refItems.get(srcGraph).get(e.getTarget()));
}
}
}
if (consistent) {
NegativeApplicationCondition newNac = NacFactory.eINSTANCE.createNegativeApplicationCondition();
for (Node n : nac.getNodes()) {
// Node newNode = n.copy();
Node newNode = InvariantCheckerUtil.copyAsPattern(n);
((PatternNode) newNode).setSameInProp(((PatternNode) n).getSameInProp());
((PatternNode) newNode).setSameInRule(((PatternNode) n).getSameInRule());
newNac.getNodes().add(newNode);
currentMatching.getNodeMatching().put(n, newNode);
}
for (Edge e : nac.getEdges()) {
// Edge newEdge = e.copy();
Edge newEdge = InvariantCheckerUtil.copyAsPattern(e);
((PatternEdge) newEdge).setSameInProp(((PatternEdge) e).getSameInProp());
((PatternEdge) newEdge).setSameInRule(((PatternEdge) e).getSameInRule());
newNac.getEdges().add(newEdge);
newEdge.setSource(currentMatching.getNodeMatching().get(e.getSource()));
newEdge.setTarget(currentMatching.getNodeMatching().get(e.getTarget()));
}
newNacs.add(newNac);
}
}
if (!newNacs.isEmpty()) {
g.setCondition(InvariantCheckerUtil.createNegatedConditions(newNacs));
}
return g;
}
return null;
}
/**
* creates the assocs between the nodes and edges of srcGraph between the
* elements of resultGraph. to make this work, all elements have be copied
* first before calling this method
*
* @param srcGraph
* the source Graph
* @param resultGraph
* the resulting graph containing then the assoc from srcGraph
*/
private void createAssocs(final Graph srcGraph, final Graph resultGraph) {
for (Iterator<Edge> iter = srcGraph.getEdges().iterator(); iter.hasNext();) {
Edge srcEdge = iter.next();
Node srcTargetNode = srcEdge.getTarget();
Node srcSourceNode = srcEdge.getSource();
Edge resultEdge = (Edge) refItems.get(srcGraph).get(srcEdge);
Node resultTargetNode = (Node) refItems.get(srcGraph).get(srcTargetNode);
Node resultSourceNode = (Node) refItems.get(srcGraph).get(srcSourceNode);
if (resultEdge != null) {
resultEdge.setSource(resultSourceNode);
resultEdge.setTarget(resultTargetNode);
}
}
}
/**
* No comment provided by developer, please add a comment to improve
* documentation.
*
* @param src
* No description provided
* @param r
* No description provided
* @return No description provided
*/
private RuleGraph copyGraph(final Graph src, final GraphRule r, boolean forward) {
RuleGraph result = null;
if (src != null && r != null) {
result = SamrulesFactory.eINSTANCE.createRuleGraph();
result.setTypedOver(src.getTypedOver());
Graph lhs = r.getLeft();
Graph rhs = r.getRight();
for (Iterator<Node> iter = src.getNodes().iterator(); iter.hasNext();) {
PatternNode nextNode = (PatternNode) iter.next();
PatternNode newNode = InvariantCheckerUtil.copyAsPattern(nextNode);
result.getNodes().add(newNode);
refItems.get(src).put(nextNode, newNode);
if (!forward) {
refItems.get(rhs).put(newNode, nextNode.getSameInRule());
} else {
refItems.get(lhs).put(newNode, nextNode.getSameInRule());
}
if (nextNode.getSameInRule() != null) {
if (nextNode.getSameInRule().eClass() == SamrulesPackage.eINSTANCE.getPreservedNode()) {
Node refInRule = ((PreservedNode) nextNode.getSameInRule()).getRefInRule();
if (!forward) {
refItems.get(lhs).put(refInRule, newNode);
} else {
refItems.get(rhs).put(refInRule, newNode);
}
newNode.setSameInRule(refInRule);
}
}
if (nextNode.getSameInProp() != null) {
newNode.setSameInProp(nextNode.getSameInProp()); // manage
// origin
// of
// new
// elements
}
}
for (Iterator<Edge> iter = src.getEdges().iterator(); iter.hasNext();) {
PatternEdge nextEdge = (PatternEdge) iter.next();
PatternEdge newEdge = InvariantCheckerUtil.copyAsPattern(nextEdge);
result.getEdges().add(newEdge);
refItems.get(src).put(nextEdge, newEdge);
if (!forward) {
refItems.get(rhs).put(newEdge, nextEdge.getSameInRule());
} else {
refItems.get(lhs).put(newEdge, nextEdge.getSameInRule());
}
if (nextEdge.getSameInRule() != null) {
if (nextEdge.getSameInRule().eClass() == SamrulesPackage.eINSTANCE.getPreservedEdge()) {
Edge refInRule = ((PreservedEdge) nextEdge.getSameInRule()).getRefInRule();
if (!forward) {
refItems.get(lhs).put(refInRule, newEdge);
} else {
refItems.get(rhs).put(refInRule, newEdge);
}
newEdge.setSameInRule(refInRule);
}
}
if (nextEdge.getSameInProp() != null) {
newEdge.setSameInProp(nextEdge.getSameInProp()); // manage
// origin
// of
// new
// elements
}
}
this.createAssocs(src, result);
}
return result;
}
public boolean checkCorrectRuleApplication(RuleGraph lhs, Graph sourceGraph) {
IsomorphicPartMatcher ipm = new IsomorphicPartMatcher();
ipm.setHostGraph(sourceGraph);
ipm.setCurrentSubGraph(SubgraphIterator.graphToSubGraph(lhs));
ipm.setPattern(lhs);
Match currentMatching = ipm.getNextMatching();
while (currentMatching != null) {
boolean consistent = true;
for (Map.Entry<Edge, Edge> e : currentMatching.getEdgeMatching().entrySet()) {
if (e.getKey() != ((PatternEdge) e.getValue()).getSameInRule()) {
consistent = false;
break;
}
}
for (Map.Entry<Node, Node> e : currentMatching.getNodeMatching().entrySet()) {
if (e.getKey() != ((PatternNode) e.getValue()).getSameInRule()) {
consistent = false;
break;
}
}
if (consistent) {
return true;
} else {
currentMatching = ipm.getNextMatching();
}
}
return false;
}
public void reset() {
refItems = new HashMap<Graph, Map<AnnotatedElem, AnnotatedElem>>();
}
}
/*
* $Log$ Revision 1.2 2007/01/03 09:27:48 basilb removed compile errors caused
* by wrong import declarations; introduced empty plugin class to ensure correct
* loading
*
*/