Skip to content

Commit

Permalink
#36 not done yet, but having a little progress
Browse files Browse the repository at this point in the history
  • Loading branch information
hoechp committed May 18, 2017
1 parent 9c20677 commit 18cd90d
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 11 deletions.
16 changes: 15 additions & 1 deletion src/main/java/org/fujaba/graphengine/PatternEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.naming.spi.DirStateFactory.Result;
Expand Down Expand Up @@ -1233,7 +1234,20 @@ public static Graph applyMatch(Match match) {
for (PatternEdge patternEdge: patternNode.getPatternEdges()) {
switch (patternEdge.getAction()) {
case "-": // remove
matchedNode.removeEdge(patternEdge.getName(), clonedNodeMatch.get(patternEdge.getTarget()));
if (patternEdge.getName() == null) {

//##### NEW TTC2017 FEATURE:

Set<String> oldKeys = new HashSet<String>(matchedNode.getEdges().keySet());
for (String s: oldKeys) { // TODO: this is experimental - too many edges could be removed...
matchedNode.removeEdge(s, clonedNodeMatch.get(patternEdge.getTarget()));
}

//#####

} else {
matchedNode.removeEdge(patternEdge.getName(), clonedNodeMatch.get(patternEdge.getTarget()));
}
break;
case "+": // create
matchedNode.addEdge(patternEdge.getName(), clonedNodeMatch.get(patternEdge.getTarget()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.fujaba.graphengine.Match;
import org.fujaba.graphengine.PatternEngine;
import org.fujaba.graphengine.graph.Graph;
import org.fujaba.graphengine.graph.Node;
import org.fujaba.graphengine.pattern.PatternAttribute;
import org.fujaba.graphengine.pattern.PatternGraph;
import org.fujaba.graphengine.pattern.PatternNode;
import org.fujaba.graphengine.stateelimination.TTCStateCaseGraphLoader;
Expand Down Expand Up @@ -56,26 +58,108 @@ public void testLoadingTTCStateCaseData() {
@Test
public void testTransformingTTCStateCaseData() {

// get data:
String taskMainPath = "src/main/resources/ExperimentalData/testdata/emf/task-main/";
Graph g = TTCStateCaseGraphLoader.load(taskMainPath + "leader3_2.xmi");

PatternGraph gtr1 = new PatternGraph("gtr1");

System.out.println("loaded:\n" + g + "\n");

// gtr for new initial state:
PatternGraph gtrInitial = new PatternGraph("new initial state");
PatternNode initialNode = new PatternNode("#{initial} == 1").addPatternAttribute(new PatternAttribute().setAction("-").setName("initial"));
PatternNode newInitialNode = new PatternNode().setAction("+").addPatternAttribute(new PatternAttribute().setAction("+").setName("newInitial").setValue(true));
PatternNode noExistingNewInitialNode = new PatternNode("#{newInitial} == 1").setAction("!=");
gtrInitial.addPatternNode(initialNode, newInitialNode, noExistingNewInitialNode);
newInitialNode.addPatternEdge("+", "", initialNode);
ArrayList<Match> matches = PatternEngine.matchPattern(g, gtrInitial, true); // just a single match
Assert.assertEquals(1, matches.size());
g = PatternEngine.applyMatch(matches.get(0));
System.out.println("added new initial state (and removed 'initial' flag for the old one):\n" + g + "\n");

// gtr for new final state:
PatternGraph gtrFinal = new PatternGraph("new final state");
PatternNode finalNode = new PatternNode("#{final} == 1").addPatternAttribute(new PatternAttribute().setAction("-").setName("final"));
PatternNode newFinalNode = new PatternNode().setAction("+").addPatternAttribute(new PatternAttribute().setAction("+").setName("newFinal").setValue(true));
PatternNode noExistingNewFinalNode = new PatternNode("#{newFinal} == 1").setAction("!=");
gtrFinal.addPatternNode(finalNode, newFinalNode, noExistingNewFinalNode);
finalNode.addPatternEdge("+", "", newFinalNode);
matches = PatternEngine.matchPattern(g, gtrFinal, true); // just a single match
Assert.assertEquals(1, matches.size());
g = PatternEngine.applyMatch(matches.get(0));
System.out.println("added new final state (and removed 'final' flag for the old one):\n" + g + "\n");

// gtr for adding to new final state:
PatternGraph gtrOtherFinal = new PatternGraph("adding to the existing new final state");
PatternNode otherFinalNode = new PatternNode("#{final == 1}").addPatternAttribute(new PatternAttribute().setAction("-").setName("final"));
PatternNode existingNewFinalNode = new PatternNode("#{newFinal} == 1");
gtrOtherFinal.addPatternNode(otherFinalNode, existingNewFinalNode);
otherFinalNode.addPatternEdge("+", "", existingNewFinalNode);
do {
matches = PatternEngine.matchPattern(g, gtrOtherFinal, true); // just a single match (each time)
if (matches != null && matches.size() > 0) {
g = PatternEngine.applyMatch(matches.get(0));
System.out.println("added edge to the new final state (and removed 'final' flag for the other one):\n" + g + "\n");
} else {
break;
}
} while (true);

// gtr for joining multiple edges between the same two nodes
/**
* this doesn't seem possible right now. you can't have a PatternGraph that says:
* 'find two (different) edges with any label between some nodes!'
*
* so we unfortunately seem to have to do this by hand:
*/
ArrayList<Node> sources = new ArrayList<Node>();
ArrayList<Node> targets = new ArrayList<Node>();
ArrayList<String> firstLabels = new ArrayList<String>();
ArrayList<String> secondLabels = new ArrayList<String>();
for (Node source: g.getNodes()) {
for (Node target: g.getNodes()) {
for (String sourceLabel1: source.getEdges().keySet()) {
if (source.getEdges(sourceLabel1).contains(target)) {
for (String sourceLabel2: source.getEdges().keySet()) {
if (!sourceLabel1.equals(sourceLabel2) && source.getEdges(sourceLabel2).contains(target)) {
sources.add(source);
targets.add(target);
firstLabels.add(sourceLabel1);
secondLabels.add(sourceLabel2);
}
}
}
}
}
}
for (int i = 0; i < sources.size(); ++i) {
sources.get(i).removeEdge(firstLabels.get(i), targets.get(i));
sources.get(i).removeEdge(secondLabels.get(i), targets.get(i));
sources.get(i).addEdge("[(" + firstLabels.get(i) + ")(" + secondLabels.get(i) + ")]", targets.get(i));
}
System.out.println("after joining multiple labels with the same sources and same targets:\n" + g + "\n");

// gtr for state elimination itself (the q->k->p to q->p case)
PatternGraph gtrEliminate = new PatternGraph("eliminate state");
PatternNode p = new PatternNode();
PatternNode k = new PatternNode();
PatternNode k = new PatternNode().setAction("-");
PatternNode q = new PatternNode();

gtr1.addPatternNode(p, k, q);

gtrEliminate.addPatternNode(p, k, q);
p.addPatternEdge("-", (String)null, k);
k.addPatternEdge("-", (String)null, q);
p.addPatternEdge("+", "calculated", q);

ArrayList<Match> matches = PatternEngine.matchPattern(g, gtr1, false);
do {
matches = PatternEngine.matchPattern(g, gtrEliminate, true); // just a single match (each time)
if (matches != null && matches.size() > 0) {
g = PatternEngine.applyMatch(matches.get(0));
System.out.println("eliminated a state (q->k->p to q->p):\n" + g + "\n");
} else {
break;
}
} while (true);

Assert.assertTrue(matches.size() > 0);
// TODO: gtr for state elimination itself (the q->k->q to q->q case)

System.out.println("yay, " + matches.size() + " matches!");
System.out.println("final graph: " + g);

}

Expand Down

0 comments on commit 18cd90d

Please sign in to comment.