package org.eclipse.emf.henshin.sam.invcheck.filter; | |
import java.util.Collection; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.Map; | |
import java.util.Set; | |
import java.util.Vector; | |
import org.eclipse.emf.henshin.sam.invcheck.SubgraphIterator; | |
import org.eclipse.emf.henshin.sam.invcheck.algorithm.IsomorphicPartMatcher; | |
import org.eclipse.emf.henshin.sam.invcheck.filter.CombinationProducer.Pair; | |
import org.eclipse.emf.henshin.sam.model.samannotation.AnnotatedElem; | |
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.samrules.GraphRule; | |
import org.eclipse.emf.henshin.sam.model.samrules.SamrulesPackage; | |
import org.eclipse.emf.henshin.sam.model.samtrace.Match; | |
public class ContainsGraphRuleHelper { | |
private GraphRule[] allRules; | |
public ContainsGraphRuleHelper(GraphRule[] rules) { | |
if (rules == null) { | |
throw new NullPointerException("null is not an allowed value for constructor parameter!"); | |
} | |
this.allRules = rules; | |
} | |
/** | |
* Looks in the given <code>Graph</code> which of the | |
* <code>GraphRules</code> known by this | |
* <code>ContainsGraphRuleHelper</code> instance are contained within it. | |
* <br/> | |
* This method returns for each urgent <code>GraphRule</code> (i.e. | |
* <code>GraphRule.isUrgent() == true</code>) all mappings of the | |
* <code>GraphRule</code> within the given <code>Graph</code>. | |
* | |
* @param graph | |
* the graph to check for contained urgen transitions | |
* @return a collection of <code>GraphRules</code> and mappings to the given | |
* <code>Graph</code> | |
*/ | |
public Collection<Pair<GraphRule, Collection<Match>>> getUrgentTransitions(Graph graph) { | |
IsomorphicPartMatcher ipm = new IsomorphicPartMatcher(); | |
ipm.setHostGraph(graph); | |
Collection<Pair<GraphRule, Collection<Match>>> result = new HashSet<Pair<GraphRule, Collection<Match>>>(); | |
for (int index = 0; index < this.allRules.length; index++) { | |
GraphRule currentRule = this.allRules[index]; | |
if (currentRule.isUrgent()) { | |
Graph tmpGraph = currentRule.getLeft(); | |
Set<AnnotatedElem> subGraph = SubgraphIterator.graphToSubGraph(tmpGraph); | |
ipm.setPattern(tmpGraph); | |
ipm.setCurrentSubGraph(subGraph); | |
Collection<Match> tmp = ipm.findAllMatchings(); | |
Vector<Match> col = new Vector<Match>(); | |
for (Match m : tmp) { | |
if (checkRuleMatchingApplicability(m)) { | |
col.add(m); | |
} | |
} | |
if (col != null && !col.isEmpty()) { | |
Pair<GraphRule, Collection<Match>> pair = new Pair<GraphRule, Collection<Match>>(currentRule, col); | |
result.add(pair); | |
} | |
} | |
} | |
return result; | |
} | |
public Map<GraphRule, Collection<Match>> findAllMatchingRules(final int priority, Graph graph) { | |
IsomorphicPartMatcher ipm = new IsomorphicPartMatcher(); | |
ipm.setHostGraph(graph); | |
Map<GraphRule, Collection<Match>> result = new HashMap<GraphRule, Collection<Match>>(); | |
for (int index = 0; index < this.allRules.length; index++) { | |
ipm.reset(); | |
GraphRule currentRule = allRules[index]; | |
if (currentRule.getPriority() > priority) { | |
Graph tmpGraph = currentRule.getLeft(); | |
ipm.setCurrentSubGraph(SubgraphIterator.graphToSubGraph(tmpGraph)); | |
ipm.setPattern(tmpGraph); | |
Collection<Match> tmp = ipm.findAllMatchings(); | |
Vector<Match> col = new Vector<Match>(); | |
for (Match m : tmp) { | |
if (checkRuleMatchingApplicability(m)) { | |
col.add(m); | |
} | |
} | |
if (col != null && col.size() > 0) { | |
result.put(currentRule, col); | |
} | |
} | |
} | |
return result; | |
} | |
/** | |
* Unfortunately, the gluing condition needs to hold for the pattern, i.e. | |
* all graphs satisfying the pattern. Therefore we cannot just check the | |
* condition for nodes from the pattern. At the moment, rules are only | |
* considered applicable if they do not contain deleted nodes. In the | |
* future, this check can be extended by searching for nacs enforcing the | |
* gluing condition and by including information from the type graph. | |
* | |
* @param matching | |
* @return | |
*/ | |
public boolean checkRuleMatchingApplicability(Match matching) { | |
for (Node ruleN : matching.getNodeMatching().keySet()) { | |
if (ruleN.eClass() == SamrulesPackage.eINSTANCE.getDeletedNode()) { | |
return false; | |
/* | |
* Node hostGraphNode = matching.getNodeMatching().get(ruleN); | |
* for (Edge e : hostGraphNode.getIncoming()) { if | |
* (!InvariantCheckingUtil.isNegated(e) && | |
* !matching.getEdgeMatching().containsValue(e)) { return false; | |
* } } for (Edge e : hostGraphNode.getOutgoing()) { if | |
* (!InvariantCheckingUtil.isNegated(e) && | |
* !matching.getEdgeMatching().containsValue(e)) { return false; | |
* } } | |
*/ | |
} | |
} | |
return true; | |
} | |
public boolean findMatchingRule(final int priority, Graph graph) { | |
IsomorphicPartMatcher ipm = new IsomorphicPartMatcher(); | |
ipm.setHostGraph(graph); | |
for (int index = 0; index < this.allRules.length; index++) { | |
ipm.reset(); | |
GraphRule currentRule = allRules[index]; | |
if (currentRule.getPriority() > priority) { | |
Graph tmpGraph = currentRule.getLeft(); | |
ipm.setCurrentSubGraph(SubgraphIterator.graphToSubGraph(tmpGraph)); | |
ipm.setPattern(tmpGraph); | |
Match currentMatch = ipm.getNextMatching(); | |
while (currentMatch != null) { | |
if (checkRuleMatchingApplicability(currentMatch)) { | |
return true; | |
} else { | |
currentMatch = ipm.getNextMatching(); | |
} | |
} | |
} | |
} | |
return false; | |
} | |
} |