blob: c923380f21932a43c0ed5d33e664f2d19f80032a [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.ecore.EObject;
import org.eclipse.emf.henshin.sam.invcheck.InvariantCheckerUtil;
import org.eclipse.emf.henshin.sam.invcheck.SubgraphIterator;
import org.eclipse.emf.henshin.sam.invcheck.adapter.GCNACAdapter;
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.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.samgraphcondition.GraphCondition;
import org.eclipse.emf.henshin.sam.model.samgraphcondition.LogicalGCCoupling;
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.SamgraphconditionPackage;
import org.eclipse.emf.henshin.sam.model.samrules.RuleGraph;
import org.eclipse.emf.henshin.sam.model.samtrace.Match;
import org.eclipse.emf.henshin.sam.model.samtrace.SamtraceFactory;
/**
* Create all possible context for one match, disjunctively combined. Try to
* eliminate disjunctive combinations to reduce NACs to one possibility. If
* there is more than one possibility, discard match and generated context. Take
* the next match, repeat. Take the next pattern, repeat.
*
* Problem: Translation of big NACs takes much time. Could order constraints by
* NAC size to alleviate this.
*
* When creating subgraphs from NACs to be matched to the target graph, we could
* check whether the rest of the NAC (connected to the positive part) contains a
* forbidden pattern. Thus, we could discard subgraphs without checking each and
* every match. Unfortunately, this has to be implemented directly in the
* NACTranslator.
*
* @author Pro
*/
public class ContextGenerator {
private Set<RuleGraph> generationConstraints;
private Set<Graph> restrictingConstraints;
private RuleGraph proofGoal;
private RuleGraph currentConstraint;
private NACTranslator nacT;
private IsomorphicPartMatcher ipm;
private Map<RuleGraph, Set<Match>> discardedMatches;
private Map<RuleGraph, Set<Match>> discardedMatchesRevertible;
public Set<RuleGraph> getGenerationConstraints() {
return this.generationConstraints;
}
public void setGenerationConstraints(Set<RuleGraph> generationConstraints) {
this.generationConstraints = generationConstraints;
}
public Set<Graph> getRestrictingConstraints() {
return this.restrictingConstraints;
}
public void setRestrictingConstraints(Set<Graph> restrictingConstraints) {
this.restrictingConstraints = restrictingConstraints;
}
public RuleGraph getProofGoal() {
return this.proofGoal;
}
public void setProofGoal(RuleGraph proofGoal) {
this.proofGoal = proofGoal;
}
/*
* public Set<RuleGraph> getCurrentConstraints() { return
* this.currentConstraints; }
*
* public void setCurrentConstraints(Set<RuleGraph> currentConstraints) {
* this.currentConstraints = currentConstraints; }
*/
public ContextGenerator() {
this.ipm = new IsomorphicPartMatcher();
this.nacT = new NACTranslator();
this.discardedMatches = new HashMap<RuleGraph, Set<Match>>();
this.discardedMatchesRevertible = new HashMap<RuleGraph, Set<Match>>();
}
public boolean proof() {
Match match = InvariantCheckerUtil.copyAsRuleGraph(this.proofGoal);
RuleGraph precondition = null;
for (Node n : match.getNodeMatching().values()) {
precondition = (RuleGraph) n.eContainer();
break;
}
nacT.setRestrictingConstraints(this.restrictingConstraints);
// int cnt = 0;
this.currentConstraint = precondition;
Iterator<RuleGraph> iter = this.generationConstraints.iterator();
while (iter.hasNext()) {
RuleGraph constraint = iter.next();
if (generateContext(constraint)) {
// cnt++;
if (checkProofGoal()) {
return true;
} else {
// reset iterator
iter = this.generationConstraints.iterator();
// delete revertible discarded matches
this.discardedMatchesRevertible.clear();
}
} else {
// do nothing, continue loop with next pattern
}
}
// System.out.println(cnt);
// iterated through all patterns without being able to generate new
// context
return false;
}
public boolean generateContext(RuleGraph pattern) {
// System.out.println("gc: " + ((NegatedCondition)
// pattern.eContainer().eContainer()).getName());
// so actually we may allow multiple NACs. Should then change this
// check.
if (pattern.getCondition() == null) {
throw new UnsupportedOperationException(
"Patterns that are used to generate context must have one or more NACs.");
}
if (pattern.getCondition().eClass() == SamgraphconditionPackage.eINSTANCE.getLogicalGCCoupling()
&& ((LogicalGCCoupling) pattern.getCondition()).getOperands().size() != 1) {
// have to see whether this will work
// throw new UnsupportedOperationException("Patterns that are used
// to generate context must have exactly one NAC.");
}
if (this.discardedMatches.get(pattern) == null) {
this.discardedMatches.put(pattern, new HashSet<Match>());
}
if (this.discardedMatchesRevertible.get(pattern) == null) {
this.discardedMatchesRevertible.put(pattern, new HashSet<Match>());
}
boolean generatedContext = false;
RuleGraph g = null;
Match tmpMatch = null;
ipm.reset();
// old version
/*
* if (this.currentConstraint.getCondition() != null) {
*
* // at this point we take one and only one NAC from the current
* constraint to match the current generating constraint in it // in
* order to also generate context for other NACs
* NegativeApplicationCondition nac =
* SamGraphInvCheckGraphAdapter.getInstance(this.currentConstraint).
* getNacs().get(0); tmpMatch = SubgraphIterator.fullNacToRuleGraph(nac,
* false); for (Node n : tmpMatch.getNodeMatching().values()) { g =
* (RuleGraph) n.eContainer(); break; } } else { tmpMatch =
* InvariantCheckingUtil.copyAsRuleGraph(this.currentConstraint); for
* (Node n : tmpMatch.getNodeMatching().values()) { g = (RuleGraph)
* n.eContainer(); break; } }
*/
Iterator<NegativeApplicationCondition> nacIter = null;
boolean first = false;
if (this.currentConstraint.getCondition() == null) {
first = true;
} else {
// remember to delete condition if we reach a point where we remove
// all conditions from current constraint. Cannot happen right now
nacIter = SamGraphInvCheckGraphAdapter.getInstance(this.currentConstraint).getNacs().iterator();
}
while (first || (nacIter != null && nacIter.hasNext())) {
NegativeApplicationCondition targetNac = null;
if (first) {
tmpMatch = InvariantCheckerUtil.copyAsRuleGraph(this.currentConstraint);
for (Node n : tmpMatch.getNodeMatching().values()) {
g = (RuleGraph) n.eContainer();
break;
}
} else {
targetNac = nacIter.next();
tmpMatch = SubgraphIterator.fullNacToRuleGraph(targetNac, false);
for (Node n : tmpMatch.getNodeMatching().values()) {
g = (RuleGraph) n.eContainer();
break;
}
}
first = false;
// old
ipm.setHostGraph(g);
ipm.setPattern(pattern);
ipm.setCurrentSubGraph(SubgraphIterator.graphToPosSubGraph(pattern));
ipm.reset();
Match nextMatch = null;
// here we could integrate a check for not only a match with the
// graph and one NAC
// but for matches with other NACs if there is more than one.
// however, we need to take care, that a match targets only the
// graph and exactly one NAC
// could just iterate over NACs and then over matches for the
// current NAC. Would just need
// to ensure that the same match in the graph will not be considered
// multiple times.
while (nextMatch == null) {
nextMatch = ipm.getNextMatching();
if (nextMatch == null) {
// System.out.println("no match: " + ((NegatedCondition)
// pattern.eContainer().eContainer()).getName());
// return false;
break;
} else {
// if (!checkMatch(nextMatch, tmpMatch, pattern) && false) {
// //System.out.println("match was discarded: " +
// ((NegatedCondition)
// pattern.eContainer().eContainer()).getName());
// nextMatch = null;
// } else
{
// match is valid, use it to generate context
nacT.reset();
nacT.setPattern(pattern);
nacT.setMergedGraph(g);
nacT.setInitialMatching(nextMatch);
RuleGraph result = null;
if (nacT.checkFullNacExistence()) {
result = null;
} else {
result = nacT.translateContext();
}
if (result == null) {
// System.out.println("translate null: " +
// ((NegatedCondition)
// pattern.eContainer().eContainer()).getName());
Match match = SamtraceFactory.eINSTANCE.createMatch();
for (Map.Entry<Node, Node> entry : nextMatch.getNodeMatching()) {
Node newValue = null;
for (Map.Entry<Node, Node> e : tmpMatch.getNodeMatching()) {
if (entry.getValue() == e.getValue()) {
newValue = e.getKey();
break;
}
}
match.getNodeMatching().put(entry.getKey(), newValue);
}
for (Map.Entry<Edge, Edge> entry : nextMatch.getEdgeMatching()) {
Edge newValue = null;
for (Map.Entry<Edge, Edge> e : tmpMatch.getEdgeMatching()) {
if (entry.getValue() == e.getValue()) {
newValue = e.getKey();
break;
}
}
match.getEdgeMatching().put(entry.getKey(), newValue);
}
this.discardedMatches.get(pattern).add(match);
nextMatch = null;
} else {
// System.out.println("translate not null: " +
// ((NegatedCondition)
// pattern.eContainer().eContainer()).getName());
if (removeInvalidNacs(result)) {
generatedContext = true;
// probably a good idea to exclude match here.
// If not, it will result in an empty
// translation the next time it is chosen and
// will then be discarded
// now we have to transform the generated NACs
// to the current NAC
if (this.currentConstraint.getCondition() == null) {
/*
* NegativeApplicationCondition newNac =
* NacFactory.eINSTANCE.
* createNegativeApplicationCondition();
* Set<NegativeApplicationCondition> nacs =
* new
* HashSet<NegativeApplicationCondition>();
* nacs.add(newNac);
* newNac.setGraph(this.currentConstraint);
* this.currentConstraint.setCondition(
* InvariantCheckingUtil.
* createNegatedConditions(nacs));
*/
targetNac = NacFactory.eINSTANCE.createNegativeApplicationCondition();
// Set<NegativeApplicationCondition> nacs =
// new
// HashSet<NegativeApplicationCondition>();
// nacs.add(targetNac);
targetNac.setGraph(this.currentConstraint);
// this.currentConstraint.setCondition(InvariantCheckingUtil.createNegatedConditions(nacs));
}
// in prior versions, we translated the result
// to the only nac in the current constraint
// now, we translate it to the nac that was used
// as a target to generate context
// NegativeApplicationCondition nac =
// GCNACAdapter.getInstance(((LogicalGCCoupling)
// this.currentConstraint.getCondition()).getOperands().get(0));
// iterate over all generated nacs
Set<NegativeApplicationCondition> newNacs = new HashSet<NegativeApplicationCondition>();
for (NegativeApplicationCondition generatedNac : SamGraphInvCheckGraphAdapter
.getInstance(result).getNacs()) {
// have to copy existing nac. Problem:
// cannot insert new nacs just yet because
// we are currently iterating over them -
// or maybe we can, because the adapter will
// not be updated when we add nacs?
NegativeApplicationCondition copyOfTargetNac = NacFactory.eINSTANCE
.createNegativeApplicationCondition();
copyOfTargetNac.setGraph(targetNac.getGraph());
Match copyOfTargetNacMatch = copyNacWithoutInterface(targetNac, copyOfTargetNac);
copyOfTargetNac.getNodes().addAll(generatedNac.getNodes());
copyOfTargetNac.getEdges().addAll(generatedNac.getEdges());
for (Edge e : copyOfTargetNac.getEdges()) {
if (!copyOfTargetNac.getNodes().contains(e.getSource())) {
for (Map.Entry<Node, Node> entry : tmpMatch.getNodeMatching()) {
if (entry.getValue() == e.getSource()) {
if (copyOfTargetNacMatch.getNodeMatching()
.containsKey(entry.getKey())) {
e.setSource(copyOfTargetNacMatch.getNodeMatching()
.get(entry.getKey()));
} else {
e.setSource(entry.getKey());
}
break;
}
}
}
if (!copyOfTargetNac.getNodes().contains(e.getTarget())) {
for (Map.Entry<Node, Node> entry : tmpMatch.getNodeMatching()) {
if (entry.getValue() == e.getTarget()) {
if (copyOfTargetNacMatch.getNodeMatching()
.containsKey(entry.getKey())) {
e.setTarget(copyOfTargetNacMatch.getNodeMatching()
.get(entry.getKey()));
} else {
e.setTarget(entry.getKey());
}
break;
}
}
}
/*
* if (e.getSource().eContainer() !=
* this.currentConstraint &&
* !copyOfTargetNac.getNodes().contains(
* e.getSource())) {
* //System.out.println(
* "nac error src/cr " + e.getName() +
* ":" + e.getInstanceOf().getName()); }
* if (e.getTarget().eContainer() !=
* this.currentConstraint &&
* !copyOfTargetNac.getNodes().contains(
* e.getTarget())) {
* //System.out.println(
* "nac error tar/cr " + e.getName() +
* ":" + e.getInstanceOf().getName()); }
*/
}
newNacs.add(copyOfTargetNac);
}
// nac.getNodes().addAll(SamGraphInvCheckGraphAdapter.getInstance(result).getNacs().get(0).getNodes());
// nac.getEdges().addAll(SamGraphInvCheckGraphAdapter.getInstance(result).getNacs().get(0).getEdges());
/*
* old for (Edge e : nac.getEdges()) { if
* (!nac.getNodes().contains(e.getSource())) {
* for (Map.Entry<Node, Node> entry :
* tmpMatch.getNodeMatching()) { if
* (entry.getValue() == e.getSource()) {
* e.setSource(entry.getKey()); break; } } } if
* (!nac.getNodes().contains(e.getTarget())) {
* for (Map.Entry<Node, Node> entry :
* tmpMatch.getNodeMatching()) { if
* (entry.getValue() == e.getTarget()) {
* e.setTarget(entry.getKey()); break; } } } }
*/
// exclude match
Match match = SamtraceFactory.eINSTANCE.createMatch();
for (Map.Entry<Node, Node> entry : nextMatch.getNodeMatching()) {
Node newValue = null;
for (Map.Entry<Node, Node> e : tmpMatch.getNodeMatching()) {
if (entry.getValue() == e.getValue()) {
newValue = e.getKey();
break;
}
}
match.getNodeMatching().put(entry.getKey(), newValue);
}
for (Map.Entry<Edge, Edge> entry : nextMatch.getEdgeMatching()) {
Edge newValue = null;
for (Map.Entry<Edge, Edge> e : tmpMatch.getEdgeMatching()) {
if (entry.getValue() == e.getValue()) {
newValue = e.getKey();
break;
}
}
match.getEdgeMatching().put(entry.getKey(), newValue);
}
this.discardedMatches.get(pattern).add(match);
// remove old NACs, add expanded NACs
EObject gcToRemove = null;
for (Edge e : targetNac.getEdges()) {
if (gcToRemove == null) {
gcToRemove = e.eContainer();
while (SamgraphconditionPackage.eINSTANCE.getNegatedCondition() != gcToRemove
.eClass()) {
gcToRemove = gcToRemove.eContainer();
}
}
e.setSource(null);
e.setTarget(null);
}
if (gcToRemove == null) {
for (Node n : targetNac.getNodes()) {
gcToRemove = n.eContainer();
while (SamgraphconditionPackage.eINSTANCE.getNegatedCondition() != gcToRemove
.eClass()) {
gcToRemove = gcToRemove.eContainer();
}
break;
}
}
this.currentConstraint.setCondition(InvariantCheckerUtil
.addNegatedConditions(this.currentConstraint.getCondition(), newNacs));
((LogicalGCCoupling) this.currentConstraint.getCondition()).getOperands()
.remove(gcToRemove);
/*
* for (Edge e :
* this.currentConstraint.getEdges()) { if
* (e.eContainer() != this.currentConstraint) {
* //System.out.println("cont error"); } if
* (e.getSource().eContainer() !=
* this.currentConstraint) {
* //System.out.println("cc error src"); } if
* (e.getTarget().eContainer() !=
* this.currentConstraint) {
* //System.out.println("cc error tar"); } } for
* (NegativeApplicationCondition nac :
* SamGraphInvCheckGraphAdapter.getInstance(this
* .currentConstraint).getNacs()) { for (Edge e
* : nac.getEdges()) { if
* (e.getSource().eContainer() !=
* this.currentConstraint &&
* !nac.getNodes().contains(e.getSource())) {
* System.out.println("nac error src"); } if
* (e.getTarget().eContainer() !=
* this.currentConstraint &&
* !nac.getNodes().contains(e.getTarget())) {
* System.out.println("nac error tar"); } } }
*/
return true;
} else {
generatedContext = true;
// there is no condition left. This means we
// have to discard the current NAC from which
// context was generated
// if there is no nac left after that, the
// positive part of the proof goal is a
// forbidden pattern
// this also means that we can prove forbidden
// patterns without nacs - however, the chance
// of failure to proof that is quite high
// we must not add this match to the discarded
// matches
/*
* Match match =
* SamtraceFactory.eINSTANCE.createMatch(); for
* (Map.Entry<Node, Node> entry :
* nextMatch.getNodeMatching()) { Node newValue
* = null; for (Map.Entry<Node, Node> e :
* tmpMatch.getNodeMatching()){ if
* (entry.getValue() == e.getValue()) { newValue
* = e.getKey(); break; } }
* match.getNodeMatching().put(entry.getKey(),
* newValue); } for (Map.Entry<Edge, Edge> entry
* : nextMatch.getEdgeMatching()) { Edge
* newValue = null; for (Map.Entry<Edge, Edge> e
* : tmpMatch.getEdgeMatching()){ if
* (entry.getValue() == e.getValue()) { newValue
* = e.getKey(); break; } }
* match.getEdgeMatching().put(entry.getKey(),
* newValue); }
* this.discardedMatchesRevertible.get(pattern).
* add(match);
*/
// need to remove the nac from which this
// context was generated
if (targetNac != null) {
for (Edge e : targetNac.getEdges()) {
e.setSource(null);
e.setTarget(null);
}
}
if (this.currentConstraint.getCondition() == null) {
// do not add a condition
} else if (SamgraphconditionPackage.eINSTANCE
.getNegatedCondition() == this.currentConstraint.getCondition().eClass()) {
// single condition, remove that. If this
// happens, we should be done with the proof
this.currentConstraint.setCondition(null);
} else if (SamgraphconditionPackage.eINSTANCE
.getLogicalGCCoupling() == this.currentConstraint.getCondition().eClass()) {
if (((LogicalGCCoupling) this.currentConstraint.getCondition()).getOperands()
.size() <= 1) {
// no or just the one condition in
// coupling. If this happens, we should
// be done with the proof
this.currentConstraint.setCondition(null);
} else {
// more than one condition in coupling
// of current constraint. have to
// continue context generation
GraphCondition gc = null;
for (GraphCondition cond : ((LogicalGCCoupling) this.currentConstraint
.getCondition()).getOperands()) {
if (GCNACAdapter.getInstance(cond).equals(targetNac)) {
gc = cond;
break;
}
}
if (gc != null) {
((LogicalGCCoupling) this.currentConstraint.getCondition()).getOperands()
.remove(gc);
} else {
throw new RuntimeException("strange error");
}
}
} else {
throw new RuntimeException("strange error");
}
return true;
}
}
}
}
}
}
return generatedContext;
}
private boolean removeInvalidNacs(RuleGraph result) {
Set<NegatedCondition> toRemove = new HashSet<NegatedCondition>();
// translate returns a coupling - if there is just one condition and
// translate ever
// returns just a negated condition, this should be changed
for (GraphCondition gc : ((LogicalGCCoupling) result.getCondition()).getOperands()) {
NegatedCondition nac = (NegatedCondition) gc;
IsomorphicPartMatcher subIpm = new IsomorphicPartMatcher();
Match match = SubgraphIterator.fullNacToGraph(GCNACAdapter.getInstance(nac), false);
Graph host = null;
for (Node n : match.getNodeMatching().values()) {
host = (Graph) n.eContainer();
break;
}
subIpm.setHostGraph(host);
for (Graph rg : this.restrictingConstraints) {
subIpm.reset();
subIpm.setPattern(rg);
subIpm.setCurrentSubGraph(SubgraphIterator.graphToSubGraph(rg));
if (subIpm.getNextMatching() != null) {
toRemove.add(nac);
break;
}
}
}
for (NegatedCondition nac : toRemove) {
Quantification quant = (Quantification) nac.getOperand();
Graph graph = quant.getContext();
for (Edge e : graph.getEdges()) {
e.setSource(null);
e.setTarget(null);
}
}
((LogicalGCCoupling) result.getCondition()).getOperands().removeAll(toRemove);
if (((LogicalGCCoupling) result.getCondition()).getOperands().size() < 1) {
// System.out.println("0 nacs left");
return false;
} else if (((LogicalGCCoupling) result.getCondition()).getOperands().size() > 1) {
// we will still return true here. Note that the generator should
// still give the correct result, as
// there will just be more nacs in the current constraint (the one
// trying to reach the proof goal.
// However, generating new nacs with generating constraints will
// just happen in the first nac in the condition.
// This is not wrong, but it is not complete either, as the
// generating constraint should be matches to all possible nacs,
// not just the first.
// System.out.println("not one nac left: " + ((LogicalGCCoupling)
// result.getCondition()).getOperands().size());
// return false;
return true;
} else {
// System.out.println("one nac left: ");
return true;
}
}
/*
private boolean checkMatch(Match chMatch, Match tmpMatch, RuleGraph pattern) {
for (Match m : this.discardedMatches.get(pattern)) {
boolean equal = true;
for (Map.Entry<Node, Node> entry : chMatch.getNodeMatching()) {
if (tmpMatch.getNodeMatching().get(m.getNodeMatching().get(entry.getKey())) != entry.getValue()) {
equal = false;
break;
}
}
if (equal) {
for (Map.Entry<Edge, Edge> entry : chMatch.getEdgeMatching()) {
if (tmpMatch.getEdgeMatching().get(m.getEdgeMatching().get(entry.getKey())) != entry.getValue()) {
equal = false;
break;
}
}
}
if (equal) {
return false;
}
// m: pattern -> host
// chMatch: pattern ->chost
// tmpMatch: host -> chost
}
for (Match m : this.discardedMatchesRevertible.get(pattern)) {
boolean equal = true;
for (Map.Entry<Node, Node> entry : chMatch.getNodeMatching()) {
if (tmpMatch.getNodeMatching().get(m.getNodeMatching().get(entry.getKey())) != entry.getValue()) {
equal = false;
break;
}
}
if (equal) {
for (Map.Entry<Edge, Edge> entry : chMatch.getEdgeMatching()) {
if (tmpMatch.getEdgeMatching().get(m.getEdgeMatching().get(entry.getKey())) != entry.getValue()) {
equal = false;
break;
}
}
}
if (equal) {
return false;
}
// m: pattern -> host
// chMatch: pattern ->chost
// tmpMatch: host -> chost
}
return true;
}
*/
public Match copyNacWithoutInterface(NegativeApplicationCondition nac, NegativeApplicationCondition newNac) {
Match match = SamtraceFactory.eINSTANCE.createMatch();
for (Node n : nac.getNodes()) {
Node newNode = InvariantCheckerUtil.copyAsPattern(n);
match.getNodeMatching().put(n, newNode);
newNac.getNodes().add(newNode);
}
for (Edge e : nac.getEdges()) {
Edge newEdge = InvariantCheckerUtil.copyAsPattern(e);
match.getEdgeMatching().put(e, newEdge);
newNac.getEdges().add(newEdge);
if (match.getNodeMatching().get(e.getSource()) != null) {
newEdge.setSource(match.getNodeMatching().get(e.getSource()));
} else {
newEdge.setSource(e.getSource());
}
if (match.getNodeMatching().get(e.getTarget()) != null) {
newEdge.setTarget(match.getNodeMatching().get(e.getTarget()));
} else {
newEdge.setTarget(e.getTarget());
}
}
return match;
}
public boolean checkProofGoal() {
// alle Graphen, die proof goal erf�llen, m�ssen auch current constraint
// erf�llen
this.ipm.reset();
this.ipm.setHostGraph(this.proofGoal);
this.ipm.setPattern(this.currentConstraint);
this.ipm.setCurrentSubGraph(SubgraphIterator.graphToSubGraph(this.currentConstraint));
return this.ipm.getNextMatching() != null;
}
/*
* @deprecated
*/
/* public void discardPatterns() {
Set<RuleGraph> toDiscard = new HashSet<RuleGraph>();
for (Graph rg : restrictingConstraints) {
ipm.reset();
}
}
*/
public Set<RuleGraph> separateContext(RuleGraph targetGraph) {
Set<RuleGraph> result = new HashSet<RuleGraph>();
for (NegativeApplicationCondition nac : SamGraphInvCheckGraphAdapter.getInstance(targetGraph).getNacs()) {
RuleGraph newGraph = null;
Match match = InvariantCheckerUtil.copyAsRuleGraph(targetGraph);
for (Node n : match.getNodeMatching().values()) {
if (n != null) {
newGraph = (RuleGraph) n.eContainer();
break;
}
}
for (Node n : nac.getNodes()) {
newGraph.getNodes().add(n);
}
for (Edge e : nac.getEdges()) {
newGraph.getEdges().add(e);
if (!newGraph.getNodes().contains(e.getSource())) {
e.setSource(match.getNodeMatching().get(e.getSource()));
}
if (!newGraph.getNodes().contains(e.getTarget())) {
e.setTarget(match.getNodeMatching().get(e.getTarget()));
}
}
result.add(newGraph);
}
return result;
}
/**
* @deprecated
* @param targetGraph
* @return
*/
public Set<RuleGraph> separateContextPositive(RuleGraph targetGraph) {
Set<RuleGraph> result = new HashSet<RuleGraph>();
for (NegativeApplicationCondition nac : SamGraphInvCheckGraphAdapter.getInstance(targetGraph).getNacs()) {
RuleGraph newGraph = null;
Match match = InvariantCheckerUtil.copyAsRuleGraph(targetGraph);
for (Node n : match.getNodeMatching().values()) {
if (n != null) {
newGraph = (RuleGraph) n.eContainer();
break;
}
}
for (Node n : nac.getNodes()) {
newGraph.getNodes().add(n);
}
for (Edge e : nac.getEdges()) {
newGraph.getEdges().add(e);
if (!newGraph.getNodes().contains(e.getSource())) {
e.setSource(match.getNodeMatching().get(e.getSource()));
}
if (!newGraph.getNodes().contains(e.getTarget())) {
e.setTarget(match.getNodeMatching().get(e.getTarget()));
}
}
result.add(newGraph);
}
return result;
}
public RuleGraph addContext(RuleGraph pattern, RuleGraph targetGraph) {
if (pattern.getCondition() == null) {
return null;
}
if (pattern.getCondition().eClass() == SamgraphconditionPackage.eINSTANCE.getLogicalGCCoupling()
&& ((LogicalGCCoupling) pattern.getCondition()).getOperands().size() != 1) {
throw new UnsupportedOperationException();
}
Graph g = null;
Match tmpMatch = null;
ipm.reset();
if (targetGraph.getCondition() != null) {
NegativeApplicationCondition nac = SamGraphInvCheckGraphAdapter.getInstance(targetGraph).getNacs().get(0);
tmpMatch = SubgraphIterator.fullNacToGraph(nac, false);
for (Node n : tmpMatch.getNodeMatching().values()) {
g = (Graph) n.eContainer();
break;
}
} else {
tmpMatch = InvariantCheckerUtil.copyAsRuleGraph(targetGraph);
for (Node n : tmpMatch.getNodeMatching().values()) {
g = (Graph) n.eContainer();
break;
}
}
ipm.setHostGraph(g);
ipm.setPattern(pattern);
ipm.setCurrentSubGraph(SubgraphIterator.graphToPosSubGraph(pattern));
Match nextMatch = ipm.getNextMatching();
if (nextMatch == null) {
return null;
}
nacT.reset();
nacT.setPattern(pattern);
nacT.setMergedGraph(targetGraph);
nacT.setInitialMatching(nextMatch);
RuleGraph result = nacT.translate();
// reform NACs in result
// for (NegativeApplicationCondition nac : )
return result;
}
/**
* @deprecated
* @param pattern
* @param targetGraph
* @return
*/
public RuleGraph addContextPositive(RuleGraph pattern, RuleGraph targetGraph) {
if (pattern.getCondition() == null) {
return null;
}
if (pattern.getCondition().eClass() == SamgraphconditionPackage.eINSTANCE.getLogicalGCCoupling()
&& ((LogicalGCCoupling) pattern.getCondition()).getOperands().size() != 1) {
throw new UnsupportedOperationException();
}
ipm.setHostGraph(targetGraph);
// have to transfer nacs to original graph
ipm.setPattern(pattern);
ipm.setCurrentSubGraph(SubgraphIterator.graphToPosSubGraph(pattern));
Match nextMatch = ipm.getNextMatching();
if (nextMatch == null) {
return null;
}
nacT.reset();
nacT.setPattern(pattern);
nacT.setMergedGraph(targetGraph);
nacT.setInitialMatching(nextMatch);
RuleGraph result = nacT.translate();
return result;
}
}